19

Possible Duplicate:
Which is best for data store Struct/Classes?

Consider the example where I have an Employee object with attributes like age, name, gender, title, salary. I now have a list i want to populate with a bunch of Employees (each Employee instance is unique).

In terms of just speed and memory footprint, is it more preferable to create the employee as a Struct or a Class?

Any additional caveats regarding Struct vs Class in the above scenario are welcome

Community
  • 1
  • 1
AMH
  • 5,779
  • 27
  • 75
  • 132
  • A few related posts: http://stackoverflow.com/questions/203695/structure-vs-class-in-c and http://stackoverflow.com/questions/608392/struct-vs-class-for-long-lived-objects but the answer to your question is probably not conclusively answerable. – Joe Sep 20 '11 at 12:01
  • 2
    @Jon: your dupe is for c++, not c#. There are differences. – Joe Sep 20 '11 at 12:01
  • 2
    Struct and Class have very different properties. If you base your choice on speed you'll get into trouble fast. – Henk Holterman Sep 20 '11 at 12:07
  • 2
    Never mind, you were too lazy to even change the question a little ... Literal copy of a question from 2007. See Matt's answer. – Henk Holterman Sep 20 '11 at 12:09
  • 1
    The source: http://discuss.joelonsoftware.com/default.asp?dotnet.12.489354.15 – Henk Holterman Sep 20 '11 at 13:44
  • Why is [Class vs Struct for data only?](http://stackoverflow.com/questions/431429/class-vs-struct-for-data-only) listed as a possible duplicate? That question is about C++, this is about C#. That's a *huge* difference. – Cornstalks Feb 17 '13 at 02:29
  • I can't believe people actually post regurgitated questions from other sites to build reputation on here. – Gavin Williams Apr 02 '17 at 09:24

3 Answers3

39

Structs are to be used only for relatively small structures that should have value-like behaviour.

Do not define a structure unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).
  • It has an instance size smaller than 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

Your type breaks the first two guidelines, and probably also the third. So you should definitely use a class here.

Mark Byers
  • 719,658
  • 164
  • 1,497
  • 1,412
  • 5
    `It will not have to be boxed frequently.` What does this mean? – alex Apr 11 '17 at 17:12
  • 5
    @alex see https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing Basically, it means casting struct to a type which will cause it to be heap allocated. (casting struct which is a value to a pointer type like object, or any interface implemented by the struct) – wingerse Jul 30 '17 at 16:17
  • 1
    How do you determine the size of an instance? – Antarr Byrd Sep 19 '17 at 13:51
  • @AntarrByrd Good question. I think one pretty much guaranteed way to get an idea would be to determine the size of the fields. For example, if an `int` is 4 bytes, then, assuming all your struct's fields would be `int`s, the struct should have at most 4 (`int`) fields (4 fields * 4 bytes = 16 bytes). – XenoRo Oct 01 '17 at 02:36
  • 1
    This does not answer the question at all. The question was about "speed and memory footprint", not the best coding practice. – FINDarkside Jan 06 '19 at 21:19
  • I think you are right in general, but have missed the most important reason for using struct over class: After the Initial copy overhead in the beginning of a data transformation pipeline, structs can perform much better with a large amount of mathematical computations over a large data set. The reason for this is they usually have better Cache Locality and therefore less cache missing when iterating over a large amount of data which means you do not have to go fetch the data all the way in RAM memory which is much slower than L# cache. This can be especially true in a multithreaded context. – Tyler Heers Jan 20 '21 at 05:17
  • Also: - It will not be pushed and poped frequently in and from the CPU stack (method parameter, especially in recursivity and in method chaining). – Olivier Rogier May 12 '21 at 21:49
13

It isn't as simple as that - you need to describe the behaviour. For example, a struct will copy itself as soon as you like, so in some ways they can consume more memory. However, an array of structs as a raw data dump can avoid a (very small) object header (and an extra dereference), so can have efficiencies.

A bigger issue, though, is in how you conceptualise them; an Employee is not a value; if I assign:

var emp = GetEmployee();
var tmp = emp;

does that mean I should now have 2 employees? It proabably doesn't. Now what if I change:

tmp.Name = "Fred";

whether this impacts emp depends on whether it is struct or class. I wager it should be class here. I also propose that a struct should almost always be immutable to avoid this type of data-loss scenario. There is case for mutable structs, but it is so often used incorrectly that I don't want to accidentally encourage you to do that.

Other issues arise with encapsulation with structs; consider that an employee has a manager; is this possible?

[struct|class] Manager {
    private Manager boss;
}

this only works for a class. Again; structs are not well suited to this type of usage. Nor polymorphism, abstraction, etc.

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • Conceptually, I think that in many ways value-type semantics are cleaner than struct semantics. Given an array of a struct like Rectangle, the effect of "ArrayOfRect[3].Width = 34;" is clear since, by definition, each element of the array refers to a different instance of Rectangle. Suppose one has an array of some rectangle-ish class and wishes to have element 3 have the same properties as it does now, except with a width of 34. How would one go about it? – supercat Oct 04 '11 at 23:49
  • @supercat your comment is unclear, as value-type===struct (and you contrast those two); also, mutable structs (`ArrayOfRect[3].Width = 34;`) are almost always a very bad idea, and lead to scenarios with subtle problems. Re the final quesiton.... er, exactly as per your example, except with a class this isn't a bad thing to do. – Marc Gravell Oct 05 '11 at 05:12
  • 1
    I thought I was contrasting struct and class, and indicating that the array-of-struct semantics are cleaner than array-of-class. Mr. Lippert really despises mutable structs because of some quirks and limitations in the way .net handles them, but they are not a "very bad idea". Everything semantically interesting about the state of a mutable struct is, outside of some (generally artificial) rare exceptions, defined by the content of its fields. By contrast, the state of an object is often determined, in significant measure, by *what references exist to it*. – supercat Oct 05 '11 at 18:06
  • If a function GetEmployeeInfo returns an EmployeeInfo plain-old-data struct, there's no question about the effect of mutating the returned struct. Changes made to the struct will affect that copy, and nothing else. The data types *completely* define the semantics. Suppose instead GetEmployeeInfo returned a mutable class. What connection would exist between the data source and the returned EmployeeInfo instance? Will changes to one update the other, corrupt the other, or have no effect on the other? One may have to examine a lot of code to really know for sure. – supercat Oct 05 '11 at 18:20
  • @supercat IMO, "plain old data struct" is *already* a misnomer. Structs are best reserved for *values*, not objects. – Marc Gravell Oct 05 '11 at 21:36
  • Exactly; if a data-holding entity should have value semantics, it should be a struct, whether or not it is mutable. Indeed, I would argue that mutability is an argument *IN FAVOR* of it being a struct. Updating mutable entities is generally more efficient than updating immutable ones, but updating a mutable class-type object without knowing whether anyone might be relying upon the old value is dangerous, and with class-type objects it's very hard to know what references might exist. – supercat Oct 06 '11 at 02:27
  • @supercat I think we fundamentally disagree; still, whatever works for you. – Marc Gravell Oct 06 '11 at 06:03
3

That depends, probably a class would be fine in this case. Hope below points help you to decide.

Use of structure in following condition is desirable.

When you have small data structure

Data Structure does not require to extent the functionality.

When you want to perform faster operation on data structure. (As structure are stored on stack, operation performed on it are faster.)

Use of class in following condition is desirable.

When you have complex data structure

Data Structure requires to extend functionality.

When you want to optimize memory usage. (As class is stored on heap, they are about to be garbage collected when no reference pointing to an object.)

Look at here for more details.

CharithJ
  • 42,659
  • 20
  • 104
  • 124