Related
This question already has answers here:
Closed 11 years ago.
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
Structs are to be used only for relatively small structures that should have value-like behaviour.
Class and struct differences
Choosing Between Classes and Structures
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.
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.
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
When to use struct in C#?
Hi, I am creating an application that has a class in C# that is purely for holding variables, it does nothing else but set and get these variables. I was wondering, for efficiency and good coding practice, if I should convert this class to a struct so that it is being used properly. I've never used structs before but have been looking into them however I am having some trouble getting it working. Any advice would be appreciated!
Thanks,
Stuart
If the collection of values model a value type (that is, something that doesn't have an identity of its own and two instances with the same values are considered the same) use a struct.
Otherwise, use a class.
Using structures in place of classes depends on the scenario on which you are working. Although you can use structures in place of classes but structures lacks the ability to implement access identifiers (such as Private, Public, Protected). If you are using classes just for holding variables, you can use structures as well, but if your class contains some private, protected or public methods or variables/properties, you can not use structures.
Hope this helps!
The decision for struct or class should be based on "do I want reference type semantics or values type semantics?"
When you use a struct as parameter, the complete contents are copied. For a class just the reference is copied. So a "big struct" could have a performance penalty!
In most cases, a class is preferred. Structs are passed by value, have no inheritance, etc. You mention efficiency, is this class likely to be a performance bottleneck ?
If you make a struct though, make sure to make it immutable
I'm not sure that using a struct or not relates to good coding practise, but there are some performance benefits to using structs under certain circumstances. For example, MSDN suggests that a type which is under 16 bytes in size might be more efficiently handled by a struct than a class.
It's important to understand why a struct might be a better choice and how their memory is managed by the runtime. Libraries which must perform quickly with the minimum of overhead would consider using structs (such as a lot of the Math types in the XNA framework). There are also design issues like the fact that your struct always has a default constructor; if you want to make sure that your type can only be constructed with specific values then a struct isn't the best choice.
The long and short of it is, unless you have a very specific reason to be using structs over classes, just stick with classes.
If you want to press ahead with structs, what issues are you having with them?
It really depends on what you're trying to achieve. The fact that you currently have only getters and setters doesn't mean anything. For example, a type might be modelling the application settings read from a file. At some point you might wish to add a IsValid() or Normalize() methods. So in this case, you'd rather go with a class then a struct.
A struct should be used, when the type's identity is decided by the value of the fields. A good example from the .NET framework is Point, which has X and Y.
The second thing is that structs should be cheap to pass to and from functions:
public bool IsInRange(Point point)
{
// ...
}
Remember that point will be copied field by field here, so that should be fairly cheap.
You use structs when:
Logically represents a single value
Has an instance size less than 16
bytes
Will not be changed after creation
Will not be cast to a reference type
Refere to MCTS 70-536
This question already has answers here:
When should I use a struct rather than a class in C#?
(31 answers)
Closed 9 years ago.
Duplicate of: When to use struct in C#?
Are there practical reasons to use structures instead of some classes in Microsoft .NET 2.0/3.5 ?
"What is the difference between structures and classes?" - this is probably the most popular question on intrviews for ".NET developer" vacancies. The only answer that interviewer considers to be right is "structures are allocated on stack and classes are allocated on heap" and no further questions are asked about that.
Some google search showed that:
a) structures have numerous limitations and no additional abilities in comparison to classes and
b) stack (and as such
structures) can be faster on very specialized conditions including:
size of data chunk less that 16 bytes
no extensive boxing/unboxing
structure's members are nearly immutable
whole set of data is not big (otherwise we get stack overflow)
(please correct/add to this list if it is wrong or not full)
As far as I know, most typical commercial projects (ERM, accouting, solutions for banks, etc.) do not define even a single structure, all custom data types are defined as classes instead. Is there something wrong or at least imperfect in this approach?
NOTE: question is about run-of-the-mill business apps, please don't list "unusual" cases like game development, real-time animation, backward compatibility (COM/Interop), unmanaged code and so on - these answers are already under this similar question:
When to use struct?
As far as I know, most typical commercial projects (ERM, accouting, solutions for banks, etc.) do not define even a single structure, all custom data types are defined as classes instead. Is there something wrong or at least imperfect in this approach?
No! Everything is perfectly right with that. Your general rule should be to always use objects by default. After all we are talking about object-oriented programing for a reason and not structure-oriented programing (structs themselves are missing some OO principles like Inheritance and Abstraction).
However structures are sometimes better if:
You need precise control over the amount of memory used (structures use (depending on the size) a little bit to FAR less memory than objects.
You need precise control of memory layout. This is especially important for interop with Win32 or other native APIs
You need the fastest possible speed. (In lots of scenarios with larger sets of data you can get a decent speedup when correctly using structs).
You need to waste less memory and have large amounts of structured data in arrays. Especially in conjunction with Arrays you could get huge amount of memory savings with structures.
You are working extensively with pointers. Then structures offer lots of interesting characteristics.
IMO the most important use case are large arrays of small composite entities. Imagine an array containing 10^6 complex numbers. Or a 2d array containing 1000x1000 24-bit RGB values. Using struct instead of classes can make a huge difference in cases like these.
EDIT:
To clarify: Assume you have a struct
struct RGB
{
public byte R,G,B;
}
If you declare an array of 1000x1000 RGB values, this array will take exactly 3 MB of memory, because the values types are stored inline.
If you used a class instead of a struct, the array would contain 1000000 references. That alone would take 4 or 8 MB (on a 64 bit machine) of memory. If you initialized all items with separate objects, so you can modify the values separately, you'd habe 1000000 objects swirling around on the managed heap to keep the GC busy. Each object has an overhead (IIRC) of 2 references, i.e. the objects would use 11/19 MB of memory. In total that's 5 times as much memory as the simple struct version.
One advantage of stack allocated value types is that they are local to the thread. That means that they are inherently thread safe. That cannot be said for objects on the heap.
This of course assumes we're talking about safe, managed code.
Another difference with classes is that when you assign an structure instance to a variable, you are not just copying a reference but indeed copying the whole structure. So if you modify one of the instances (you shouldn't anyway, since structure instances are intended to be immutable), the other one is not modified.
All good answers thus far...I only have to add that by definition value types are not nullable and hence are a good candidate for use in scenarios where you do not want to be bothered with creating a new instance of a class and assigning it to fields, for example...
struct Aggregate1
{
int A;
}
struct Aggregate2
{
Aggregate1 A;
Aggregate1 B;
}
Note if Aggregate1 were a class then you would have had to initialize the fields in Aggregate2 manually...
Aggregate2 ag2 = new Aggregate2();
ag2.A = new Aggregate1();
ag2.B = new Aggregate1();
This is obviously not required as long as Aggregate1 is a struct...this may prove to be useful when you are creating a class/struct heirarchy for the express purpose of serialization/deserialization with the XmlSerializer Many seemingly mysterious exceptions will disappear just by using structs in this case.
If the purpose of a type is to bind a small fixed collection of independent values together with duct tape (e.g. the coordinates of a point, a key and associated value of an enumerated dictionary entry, a six-item 2d transformation matrix, etc.), the best representation, from the standpoint of both efficiency and semantics, is likely to be a mutable exposed-field structure. Note that this represents a very different usage scenario from the case where a struct represents a single unified concept (e.g. a Decimal or DateTime), and Microsoft's advice for when to use structures gives advice which is only applicable to the latter one. The style of "immutable" structure Microsoft describes is only really suitable for representing a single unified concept; if one needs to represent a small fixed collection of independent values, the proper alternative is not an immutable class (which offers inferior performance), nor a mutable class (which will in many cases offer incorrect semantics), but rather an exposed-field struct (which--when used properly--offers superior semantics and performance). For example, if one has a struct MyTransform which holds a 2d transformation matrix, a method like:
static void Offset(ref it, double x, double y)
{
it.dx += x;
it.dy += y;
}
is both faster and clearer than
static void Offset(ref it, double x, double y)
{
it = new Transform2d(it.xx, int.xy, it.yx, it.yy, it.dx+x, it.dy+y);
}
or
Transform2d Offset(double dx, double dy)
{
it = new Transform2d(xx, xy, yx, yy, dx+x, dy+y);
}
Knowing that dx and dy are fields of Transform2d is sufficient to know that the first method modifies those fields and has no other side-effect. By contrast, to know what the other methods do, one would have to examine the code for the constructor.
There have been some excellent answers that touch on the practicality of using structs vs. classes and visa-versa, but I think your original comment about structs being immutable is a pretty good argument for why classes are used more often in the high-level design of LOB applications.In Domain Driven Design http://www.infoq.com/minibooks/domain-driven-design-quickly there is somewhat of a parallel between Entities/Classes and Value Objects/Structs. Entities in DDD are items within the business domain whose identity we need to track with an identifier, e.g. CustomerId, ProductId, etc. Value Objects are items whose values we might be interested in, but whose identity we don't track with an identifier e.g Price or OrderDate. Entities are mutable in DDD except for their Identity Field, while Value Objects do not have an identity.So when modeling a typical business entity, a class is usually designed along with an identity attribute, which tracks the identity of the business object round trip from the persistance store and back again. Although at runtime we might change all the property values on a business object instance, the entity's identity is retained as long as the identifier is immutable. With business concepts that correspond to Money or Time, a struct is sort of a natural fit because even though a new instance is created whenever we perform a computation, that's ok because we aren't tracking an identity, only storing a value.
sometime, you just wanna transfer data between components, then struct is better than class. e.g. Data Transfer Object(DTO) which only carry data.
I like using structs a lot.
So after reading this article, are there any other concerns I should have against using them all the time?
See Also:
When should I use a struct instead of a class?
When to use struct in C#?
You should make the following considerations about structs:
structs should be immutable (mutable structs are not intuitive and unpredictable)
structs always have a default (public parameterless) constructor that cannot be changed
struct size should not exceed 16 bytes
the Equals and GetHashCode methods should be overriden for better performance
implementing the IEquatable<T> interface is recommended
redefining and == and the != operators is also recommended
I almost never define custom structs. There just aren't that many natural value types around, IMO.
In particular, I would think very, very carefully before defining a mutable struct, especially if it mutates via an interface implementation. Mutable structs behave in ways which people don't expect at all, leading to code which is hard to understand.
I think it's worth reading "Choosing Between Classes and Structures" from "Design Guidelines For Developing Class Libraries".
In particular:
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.
Do you really develop types with all of those characteristics frequently?
They don't fit into an Object Oriented programming paradigm like classes do. They are good for small data structures, but I use classes for anything beyond that.
I think main purpose of a struct - to keep only variable types. If you keep some classes into struct - you're wrong.
Ask yourself the following questions about the set of data you're modeling with a struct:
Might it ever need to have any
get/set logic?
Might it ever need to store ANY logic
that is endemic to the data?
Might it need to inherit another set
of data?
Might another set of data need to
inherit this one?
I think if you can heartily answer "no" to all these questions, then there's no good reason not to use a struct. I think people use static subclasses in certain situations where a struct would be more than good enough.
A class is a lot simpler to implement correctly than a struct. If you implement a struct incorrectly it can give you some unexpected errors.
A struct should not be larger than 16 bytes, or you lose most of the performance benefits.
A struct is intended to be a value type, representing a single entity of some kind.
A struct should be immutable. That means that you never change one of the properties in a struct. If you want a struct value that is different you create a new value.
Use of structs should be limited to when all you really need is a small data structure. (as you read). I would only really use them for the smallest of datastructures like coordinates, offsets, and sometimes for graphics.
In many ways, you can think of structs in C# as being like scaled - down classes. They are basically the same as classes but designed more for cases where you simply want to group some data together. They
differ from classes in the following ways:
Some things to keep in mind
Structs are value types, not
reference types. This means they are
stored either in the stack or in-
line (if they are part of another
object that is stored on the heap)
and have the same lifetime
re-strictions as the simple data
types.
Structs do not support inheritance.
There are some differences in the
way constructors work for structs.
In particular, the compiler always
supplies a default no - parameter
constructor, which you are not
permitted to replace.
MSDN says that a class that would be 16 bytes or less would be better handled as a struct [citation].
Why is that?
Does that mean that if a struct is over 16 bytes it's less efficient than a class or is it the same?
How do you determine if your class is under 16 bytes?
What restricts a struct from acting like a class? (besides disallowing parameterless constructors)
There are a couple different answers to this question, and it is a bit subjective, but some reasons I can think of are:
structs are value-type, classes are reference type. If you're using 16 bytes for total storage, it's probably not worth it to create memory references (4 to 8 bytes) for each one.
When you have really small objects, they can often be pushed onto the IL stack, instead of references to the objects. This can really speed up some code, as you're eliminating a memory dereference on the callee side.
There is a bit of extra "fluff" associated with classes in IL, and if your data structure is very small, none of this fluff would be used anyway, so it's just extra junk you don't need.
The most important difference between a struct and a class, though, is that structs are value type and classes are reference type.
By "efficient", they're probably talking about the amount of memory it takes to represent the class or struct.
On the 32-bit platform, allocating an object requires a minimum of 16 bytes. On a 64-bit platform, the minimum object size is 24 bytes. So, if you're looking at it purely from the amount of memory used, a struct that contains less than 16 bytes of data will be "better" than the corresponding class.
But the amount of memory used is not the whole story. Value types (structs) are fundamentally different than reference types (classes). Structs can be inconvenient to work with, and can actually cause performance problems if you're not careful.
The real answer, of course, is to use whichever works best in your situation. In most cases, you'll be much better off using classes.
Check this link, I found it on one of the answers in SO today: .NET Type Internals. You can also try searching SO and Googling for "reference types vs value types" for differences between structs and classes.
What restricts a struct from acting like a class?
There are many differences. You cannot inherit from a struct, for example.
You can't have virtual methods, so you cannot use a struct to implement an interface. Instance methods in structs can access struct's private fields, but apart from that they behave a lot like auxilirary "helper" functions (for immutable structs, they sometimes don't even need to access private data). So I find them to be not as near as "valuable" as class methods.
structs are different from classes because they are stored on the stack, and not on the heap. That means that every time you call a method with the struct as parameter, a copy is created and passed to the method. That is why large structs are extremely inefficient.
I would actively discourage to use structs nevertheless, because it could cause some subtle bugs: e.g. when you change a field of a struct, its not going to be reflected for the caller (because you only changed the copy) - which is completely different behavior to classes.
So the 16 bytes I think is a reasonable maximum size of a struct, but still in most cases it is better to have a class. If you still want to create a struct, try to make it immutable at least.
This is due to the different way that the CLR handles structs and classes. Structs are value types which means they live on the stack rather than in the managed heap. It is a good rule of thumb to keep structs small because once you start passing them as method arguments you will incur overhead as structs are copied in their entirety when passed to a method.
Since classes pass a copy of their reference to methods they incur much less overhead when used as method arguments.
The best way to determine the size of your class is to total the number of bytes required by all the members of your class plus an extra 8 bytes for CLR overhead stuff (the sync block index and the reference to the type of the object).
In memory, the struct will hold the data directly, while a class will behave more like a pointer. That alone makes an important difference, since passing the struct as a parameter to a method will pass its values (copy them on the stack), while the class will pass the reference to the values. If the struct is big, you will be copying a lot of values on each method call. When it is really small copying the values and using them directly will be probably faster than copying the pointer and having to grab them from another place.
About restrictions: you can't assign it to null (although you can use Nullable<>) and you have to initialize it right away.
Copying an instance of a struct takes less time than creating a new instance of a class and copying data from an old one, but class instances can be shared and struct instances cannot. Thus, "structvar1 = structvar2" requires copying new struct instance, whereas "classvar1 = classvar2" allows classvar1 and classvar2 refer to the same struct instance (without having to create a new one).
The code to handle the creation of new struct instances is optimized for sizes up to 16 bytes. Larger structs are handled less efficiently. Structs are a win in cases where every variable that holds a struct will hold an independent instance (i.e. there's no reason to expect that any particular two variables will hold identical instances); they are not much of a win (if they're a win at all) in cases where many variables could hold the same instance.