6

C# question.
Say I have a customers class that has a bunch of props for storing string only data such as name postal data and phone numbers.

I don't use this entity for ORM as I'm only adding it to some type of collection for use during app life cycle. Additionally I don't need to add any entity specific methods to it or persist the data to xml or database, or even to a webservice.

Is it better to make this a struct rather than a class? or no benefit? Also side question, should I make the collection Customers, a list structure?

Be harsh, please critique.. :)

 struct customer
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

    }

struct Customers<List>
{
    private customer cust;

    public customer Cust
    {
        get { return cust; }
        set { cust = value; }
    }

}
Anonymous Type
  • 3,051
  • 2
  • 27
  • 45

5 Answers5

5

I can't see any value in making the customer a struct. The string fields will all be reference types, so you might as well make the whole thing a reference type (ie. class).

I'd be inclined to use one of the built-in collection types rather than create my on type for Customers. Something like:

List<Customer> Customers = new List<Customer>();
Andrew Cooper
  • 32,176
  • 5
  • 81
  • 116
  • thanks, this is the type of answer I was hoping for cheers mate. btw do you think other than wrapping a whole bunch of reference types in a value type, there would be a small performance gain when building a large dataset of "customers"? i know I should test just wondering. – Anonymous Type Oct 25 '10 at 03:23
  • 1
    I think you'd have to test the performance. It probably depends a lot on how many fields you're talking about, and what you're doing with them. You won't get much gain in performance during object creation because memory has to be allocated for the strings anyway. – Andrew Cooper Oct 25 '10 at 03:29
  • 1
    @Anonymous: Also, don't forget that though the garbage collection cost of a large struct full of reference types can be a *tiny* amount faster than that of a class full of reference types, the cost *every single time you copy it* is *much larger*. Value types are not free; they are copied by value, and that can be very slow compared to a reference copy. Entire nanoseconds slower! – Eric Lippert Oct 25 '10 at 14:06
  • ahh excellent point Eric, thankyou this is exactly the kind of detail that makes SO such a great place to ask questions. – Anonymous Type Oct 25 '10 at 21:17
  • one advantage of using a struct is to avoid checking for nulls in the rest of the code as when it was a reference type or a plain string; from this perspective wrapping a primitive type `string` into a domain concept also makes sense. – Califf Feb 21 '23 at 16:29
3

I suppose you could look at When to use struct in C#?

Community
  • 1
  • 1
Dynami Le Savard
  • 4,986
  • 2
  • 26
  • 22
  • yeah thanks for the link, if you read the constraints of the question I'm only using it for storing some string data during application execution, so why do any of the points in the question you linked refute use of a struct? – Anonymous Type Oct 25 '10 at 03:21
2

Unless you have identified specific reasons for using a struct, use a class.

Update: due to @Dmitry Lobanov: Eric Lippert's post: The Truth About Value Types

Structs vs. Classes

Structs may seem similar to classes, but there are important differences that you should be aware of. First of all, classes are reference types and structs are value types. By using structs, you can create objects that behave like the built-in types and enjoy their benefits as well.

Heap or Stack?

When you call the New operator on a class, it will be allocated on the heap. However, when you instantiate a struct, it can be created on the stack. This will yield performance gains. Also, you will not be dealing with references to an instance of a struct as you would with classes. You will be working directly with the struct instance. Because of this, when passing a struct to a method, it's passed by value instead of as a reference.

Ref.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • well i guess that's what my question is asking Mitch, have i identified a specific reason (such as performance) for using a struct? Since I'm not going to reuse the entities that are storing the customer data, using a struct shouldn't be ruled out. Just because its a "Customer" type given my constraints why shouldn't I use a struct? – Anonymous Type Oct 25 '10 at 03:19
  • Well, I think the things are bit more complicated, here's a great post about value types misunderstanding: http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx – Dmitrii Lobanov Oct 25 '10 at 04:34
1

For what it's worth, I would never use structs because I so very rarely have a need to provide a data only structure that doesn't have some sort of associated behaviour (validators, formatters, etc...).

The one thing that I do like about the basic concept of a "struct" is that it represents a storage system at it's most basic, and therefore should avoid the need to write all those pernickity custom getters and setters and all that sort of stuff... but then again, we now have those lovely auto-properties which effectively achieve the same result from purely a coding perspective, and while the YAGNI nazi in me might say to use the struct because it is meant to be simple, the realist in me knows that I will inevitably want to change the struct to a class anyway, so why not simply implement the class from the beginning and be done with the matter! ;-)

As for the argument of performance, and other benefits... ask yourself the question "does this really matter". If you're writing a serious real-time system... perhaps you want to be using another tool. If you're simply passing around some data, you've likely got oodles of processing croutons at your disposal, and your killer algorithm might not really need to worry about the nano-second difference it's going to make.

S.Robins
  • 703
  • 6
  • 6
0

Personally I use structs everywhere I need to store information, as long as it will not cause obvious performance issues. In most projects this is never, since the data is either directly mappable to an existing type or is larger than a reference (affecting the invariable LINQ queries and other manipulation). I find that structs are only viable when I can stick the data in an array and leave it there (modifying the variables directly in the array), the struct is rarely used, or the amount of data in the struct is less than 64 bits (ignoring struct overhead).

As it was explained to me, structs should be used only to store data and translate it from one form to another (ToString or ToArray converters).

Also, structs are more restrictive than classes with the primary differences:

  • Structs are value types while classes are reference types. This means the whole struct instance is copied when it is assigned while only the memory address of a class instance is copied. Since most programs are 32bit or 64bit it is usually recommended to limit the size of the struct to prevent performance issues related to copying struct instances as compared to class instanceses. While this can be overcome by putting the structs in an array, this moves the structs to the heap (instead of stack). Also, using generics like List always returns a copy of the instance, since they use methods to access the values. See also the Struct Instances vs. Class Instances section in Objects (C# Programming Guide)
  • Structs can be instantiated on the stack, while classes are always instantiated on the heap. This is controlled by the compiler and does not affect coding, though it may have a small performance benefit (which is rarely ever detectable).
  • Within a struct declaration, fields cannot be initialized unless they are declared as const or static.
  • A struct cannot declare a default constructor (a constructor without parameters) or a destructor.
  • Unlike classes, structs can be instantiated without using a new operator.
  • A struct cannot inherit from another struct or class, and it cannot be the base of a class.
  • All structs inherit directly from System.ValueType, which inherits from System.Object while classes inherit from System.Object.
  • A struct cannot be null (use the generic Nullable struct).
Trisped
  • 5,705
  • 2
  • 45
  • 58
  • There is nothing wrong with having a struct contain references to immutable objects; further, the break-even size for using a structure versus an immutable class object type depends upon how often the things in question get passed around. If an struct would get boxed, a class object will win. Otherwise, unless a thing would get copied at least three times there is no break-even point (struct of any size wins), and unless it gets copied dozens of times even a 100-byte structure would outperform a 100-byte class object. – supercat Apr 29 '15 at 19:02
  • @supercat Sorry, that first version was poorly written. Is that more clear? – Trisped Apr 30 '15 at 17:25
  • Even though object references are small, every object will have a header cost equivalent to two object references, and IIRC a minimum payload size of two object references. Thus, if N references exist to an object whose size is equivalent to S object references (S >= 2), the total memory cost will be equivalent to N+S+2 object references. If N will be 4, a struct will almost certainly be more efficient unless S exceeds 2; if N is 2, a struct will almost certainly be more efficient unless S exceeds 4. In practice, the overhead associated with class object is sufficient that... – supercat Apr 30 '15 at 17:38
  • ...in practice S and N generally have to be even bigger than those values in order for class objects to come out ahead. Your quoted 64 bits is way below the break-even point. – supercat Apr 30 '15 at 17:39
  • @supercat I am not nitpicking 8 bytes of RAM, I am concerned about moving and modifying the properties of the instances (CPU of move, RAM usage of duplicates). If you only have to move a few instances it does not matter either way (so use the default class). If you have to move a large number of instances, then class will be more efficient, because you are only copying pointers, not the whole instance. – Trisped Apr 30 '15 at 18:56
  • @supercat It sounds to me like you have some pretty strong opinions. Why don't you get some references to back them up and post an answer? – Trisped Apr 30 '15 at 18:57