0

I have a list of 50 attributes that an object can have. This object can have different categories of properties - category 1, category 2 and category 3. Category 1 is subset of category 2, category 2 is subset of category 3, and category 3 is the full list. I've initially used struct but I'm now wondering if I should use class, or if I'm going about it the wrong way in the first place. For the sake of let's trim it down to 5 attributes and just 2 categories.

C1: A1, A2, A3
C2: A1, A2, A3, A4, A5

The main thing I want to do is to save the struct or class on my main class without differentiating between the two. If I'm using a class, I could create a base class that the 2 category class can be derived from and save it as base class:

Category category;
...
category = new Category1();
category = new Category2();

Since I'm dealing with 10, 25, 50 attribute per category, the class definition is just a large list of properties which looks like struct would be a better fit. But if I use struct, it looks like I have to save it on as Object type? That seems kludgy.

What would be the right way to go about this?


Let me sneak in a second question here. :) So, since I have a large list of properties per class(or struct), would it be better to use object initializer instead of having a constructor with 10, 25, 50 parameters?

blissfool
  • 1,007
  • 1
  • 12
  • 21
  • 1
    As a rule, don't use a struct unless you have a good reason. Default to classes. Structs are value types, which can cause unexpected behaviour, especially if you make them mutable. Also because they are value-types, they should be small; 50 members is too many for a struct. – Blorgbeard Oct 23 '14 at 22:20
  • @Blorgbear - Thanks. Those are the reasons why I wanted to get some feedback. These fields will be immutable in the finished product but structs are value type ... but 50 fields are too much. etc. etc. Haha. It looks like I will be sticking with classes. – blissfool Oct 24 '14 at 16:59

4 Answers4

2

You should only define a struct when:

  • It represents a single value (similar to int, double, long, ...)
  • It's smaller than 16 bytes
  • It's not mutable
  • You don't expect it to be boxed often

I think the real question is why do you have a class with 50 properties. You should probably look into creating smaller logical classes.

Kenneth
  • 28,294
  • 6
  • 61
  • 84
  • Thank you for your reply. I wasn't aware of such restrictive recommended practice. Many references mentions using struct as a place holder for records, so I thought it might be a good use for this. As for the number of properties, I am currently writing some experimental code that parses crudely formatted data and I'm trying to create a model based on it. I am currently not sure how else to logically structure them at the moment. – blissfool Oct 24 '14 at 15:15
0

What are you going to do with that category variable?

Use classes. I don't think you want value semantics, and you won't get them very often anyway. Too much data. It sounds like plain old class inheritance is what you need, if these are DTO's.

class Category1 {
  public int A1 { get; set; }
  public int A2 { get; set; }
  public int A3 { get; set; }
}

class Category2 : Category1 {
  public int A4 { get; set; }
  public int A5 { get; set; }
}

I would start with initializers, because the constructors would be maintenance. But, if you do initialize them a lot, then constructors with defaults will allow you to use named parameters to great effect. So, it depends.

BnWasteland
  • 2,109
  • 1
  • 18
  • 14
  • Well, once the field are set, I will just be making them available to an instance of an analyzer class. The fields won't change once they are set but I'm not sure if I will make the setter private since that would mean I can't use object initializer. It's still an experimental code so I'm not too worried about that level of semantics. Just want to at least model the data as well as possible. – blissfool Oct 24 '14 at 15:23
  • Just to add, I have the classes currently setup as your example but I also had a private setter and constructor. And, by the time I was setting up constructor for category 3 class, the list of parameter became so long that I stopped, thinking this can't be right. Before the question was posted, I've changed my code to look like your example and started to use object initializer. Then I decided to ask for some suggestion on different approach. – blissfool Oct 24 '14 at 15:27
0

You can create either a class or a struct, it depends on how you're going to use them, but generally you should just use classes. Check out: http://msdn.microsoft.com/en-us/library/ms173109.aspx for more details.

In answer to your second question, constructors with arguments should be created for args that don't have a good default value. Otherwise object initializers are great.

You might want to reconsider your design, however. Most well designed classes will not have that many properties. Good design principles usually guide you to create methods that do one thing really well, and classes that represent the smallest representation of what you're modelling. In other words, if your class is modelling a Car, it would most likely have properties for the large components that are represented by other, smaller classes.

Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • Thank you. Most of the fields are just primitive type so I believe they have a good default value. As I've mentioned in the comment for Kenneth's answer, "I am currently writing some experimental code that parses crudely formatted data and I'm trying to create a model based on it. I am currently not sure how else to logically structure them at the moment." – blissfool Oct 24 '14 at 15:18
0

In many cases, it can be helpful to aggregate many of the fields of a class into a private exposed-field structure type. The purpose of this is entirely different from the usage scenario envisioned by the author of the oft-cited "rules for structures" document, so the suggestions therein are not meaningful here. If e.g. you encapsulate most of the primary fields into a type PrimaryFieldStruct, and your class has a field of that type called pf, then accessing any field of that struct will have just the same cost as it would have if the field were a member of the class rather than part of the struct. Having the fields aggregated as type PrimaryFieldStruct, however, will give you the ability to copy all of the fields from one class instance to another.

supercat
  • 77,689
  • 9
  • 166
  • 211