I know something about struct type. But I can't understand: what is it for? when have I use it? Classes, simple value-types and enums - that's all that I need.
Any suggestions?
UPD: PLEASE! Don't tell me that struct is in the stack (I know this :). What struct is for?
You choose a struct if you want value-type semantics. You choose a class if you want reference-type semantics. All other concerns are secondary to this one.
MSDN provdies a guide : Choosing Between Classes and Structures:
Consider defining a structure instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
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.
Things that should be a struct (because they are values):
struct Color
struct Point
struct Rectangle
struct GLVertex (contains location, color, normal and texcoord)
struct DateTime
Things that should be a class (because they are things to which you refer):
class RandomGenerator
class Socket
class Thread
class Window
Why?
Consider the following code.
class Button
{
public Point Location { get; set; }
}
class Program
{
public static void Main()
{
var button = Util.GetButtonFromSomewhere();
var location = button.Location;
Util.DrawText("one", location);
location.Y += 50;
Util.DrawText("two", location);
location.Y += 50;
Util.DrawText("three", location);
}
}
This will draw 3 text labels, vertically aligned. But if Point is a class, this will also move the button, which is really unexpected: var location = button.Location feels like it should copy a value, and not a reference! In other words, we think of Point as a value type and not a reference type. "value" here is used in the mathematical sense of value. Consider the number 5, it's an abstract object "somewhere out there", you just "refer" to it. Similarly, a Point simply is. It doesn't reside anywhere, we can't change it. Therefore we choose to make it a struct, so it has the semantics users expect.
On the other hand, we could have class Button { public Window Parent { get; set; } }. Here, Parent is an entity, so we represent it with a reference type - Window. It may make sense to use code like myButton.Parent.Redraw();. So Window should be a class.
So far so good. But all this probably sounds too vague to you. How do you really decide if something "feels" like a reference or a value? My rule of thumb is simple:
What should Foo a = b; a.Mutate(); do?
If it seems like it should leave b unchanged, make Foo a struct.
Otherwise make it a class.
Use the principle of least surprise here.
Simple value types are best implemented via a struct.
Struct Usage Guidelines
It is recommended that you use a
struct for types that meet any of the
following criteria:
* Act like primitive types.
* Have an instance size under 16 bytes.
* Are immutable.
* Value semantics are desirable.
You must also understand that a class instance is allocated on the heap.
A struct -is a vallue type- and is allocated on the stack.
First you must understand the difference between value-type and reference type. I will assume since you said to skip that part that you understand what it is.
Struct is a value-type and you get all of the privileges that you would get working with a value-type.
Structs are passed around by value. When you do something like
DateTime time = new DateTime();
DateTime newTime = time;
// you are not referencing time
// instead you have created a new instance
Structs are NOT lightweight classes they may have many methods, just look at DateTime struct.
Structs maybe lighter in performance, but not all the time. Consider passing a large struct to a method. Because structs are value-types each time you pass one into a method a new instance of the struct is created, hence copying the struct each time. If you have a fairly large struct this will be a much larger performance hit.
You may have to occasionally box and unbox structs, since they are value types.
In short, use a struct to represent an atomic value in memory.
Youcan use structs when you want a "class" with value (rather than reference) semantics.
structs are for objects that represent something whose identity is defined by the values stored in it's properties rather than by an Id or key. These are called "Value types" as opposed tyo objects called "Entity Types", whose identity persists over time and is not dependant on the values of the properties of the object.
As an example, a Person class (an Entity) has an identity that persists from one session to another, even from year to year, in spite of how the Person's address, phone number, employer, etc might change from one instance to another. If you inadvertently have two instances of a Person class in memory at the same time, which represent the same individual/entity, then it is important that they have the same values for their properties.
A CalendarMonth object otoh, (a value type) only has identity defined by the value which specifies which calendar month it is... no matter how many instances of "March 2009" you might be using, they are all interchangeable and equivilent. Another example might be an object representing a FiscalYear designation in a tax program. A great example is an address object. (Not talking here about the asociation of an address with a person or a business, or any other entity, but just the address itself). Changing just about any property of an address makes it a different address. Once you create an address object in memory, it is equivilent and interchangeable with every other address object that has the same properties. This is why these value types should generally be immutable. When you need one, create a new one with the property value(s) you need, and throw it away when you're done using it.
If you don't know why you need it, you probably don't.
struct is a value type rather than a reference type. If you don't know what that means, then you probably aren't going to need it.
Example: Say you want a data type to represent Coordinates at X Y Z. You don't really need any functionality, only three variables. A struct would be good for this, a class may be overkill.
In reality, I think struct is an legacy from C. I do not think we MUST use it in any condition. Perhaps sometime you feel that leaving something on stack rather than on heap is more efficient; but as Java/C# never takes efficient as its first stand, so just neglect it:) That's my opinion.
Related
I know that structs in .NET do not support inheritance, but its not exactly clear why they are limited in this way.
What technical reason prevents structs from inheriting from other structs?
The reason value types can't support inheritance is because of arrays.
The problem is that, for performance and GC reasons, arrays of value types are stored "inline". For example, given new FooType[10] {...}, if FooType is a reference type, 11 objects will be created on the managed heap (one for the array, and 10 for each type instance). If FooType is instead a value type, only one instance will be created on the managed heap -- for the array itself (as each array value will be stored "inline" with the array).
Now, suppose we had inheritance with value types. When combined with the above "inline storage" behavior of arrays, Bad Things happen, as can be seen in C++.
Consider this pseudo-C# code:
struct Base
{
public int A;
}
struct Derived : Base
{
public int B;
}
void Square(Base[] values)
{
for (int i = 0; i < values.Length; ++i)
values [i].A *= 2;
}
Derived[] v = new Derived[2];
Square (v);
By normal conversion rules, a Derived[] is convertible to a Base[] (for better or worse), so if you s/struct/class/g for the above example, it'll compile and run as expected, with no problems. But if Base and Derived are value types, and arrays store values inline, then we have a problem.
We have a problem because Square() doesn't know anything about Derived, it'll use only pointer arithmetic to access each element of the array, incrementing by a constant amount (sizeof(A)). The assembly would be vaguely like:
for (int i = 0; i < values.Length; ++i)
{
A* value = (A*) (((char*) values) + i * sizeof(A));
value->A *= 2;
}
(Yes, that's abominable assembly, but the point is that we'll increment through the array at known compile-time constants, without any knowledge that a derived type is being used.)
So, if this actually happened, we'd have memory corruption issues. Specifically, within Square(), values[1].A*=2 would actually be modifying values[0].B!
Try to debug THAT!
Imagine structs supported inheritance. Then declaring:
BaseStruct a;
InheritedStruct b; //inherits from BaseStruct, added fields, etc.
a = b; //?? expand size during assignment?
would mean struct variables don't have fixed size, and that is why we have reference types.
Even better, consider this:
BaseStruct[] baseArray = new BaseStruct[1000];
baseArray[500] = new InheritedStruct(); //?? morph/resize the array?
Structs do not use references (unless they are boxed, but you should try to avoid that) thus polymorphism isn't meaningful since there is no indirection via a reference pointer. Objects normally live on the heap and are referenced via reference pointers, but structs are allocated on the stack (unless they are boxed) or are allocated "inside" the memory occupied by a reference type on the heap.
Class like inheritance is not possible, as a struct is laid directly on the stack. An inheriting struct would be bigger then it parent, but the JIT doesn't know so, and tries to put too much on too less space. Sounds a little unclear, let's write a example:
struct A {
int property;
} // sizeof A == sizeof int
struct B : A {
int childproperty;
} // sizeof B == sizeof int * 2
If this would be possible, it would crash on the following snippet:
void DoSomething(A arg){};
...
B b;
DoSomething(b);
Space is allocated for the sizeof A, not for the sizeof B.
Here's what the docs say:
Structs are particularly useful for small data structures that have value semantics. Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. Key to these data structures is that they have few data members, that they do not require use of inheritance or referential identity, and that they can be conveniently implemented using value semantics where assignment copies the value instead of the reference.
Basically, they're supposed to hold simple data and therefore do not have "extra features" such as inheritance. It would probably be technically possible for them to support some limited kind of inheritance (not polymorphism, due to them being on the stack), but I believe it is also a design choice to not support inheritance (as many other things in the .NET languages are.)
On the other hand, I agree with the benefits of inheritance, and I think we all have hit the point where we want our struct to inherit from another, and realize that it's not possible. But at that point, the data structure is probably so advanced that it should be a class anyway.
Structs are allocated on the stack. This means the value semantics are pretty much free, and accessing struct members is very cheap. This doesn't prevent polymorphism.
You could have each struct start with a pointer to its virtual function table. This would be a performance issue (every struct would be at least the size of a pointer), but it's doable. This would allow virtual functions.
What about adding fields?
Well, when you allocate a struct on the stack, you allocate a certain amount of space. The required space is determined at compile time (whether ahead of time or when JITting). If you add fields and then assign to a base type:
struct A
{
public int Integer1;
}
struct B : A
{
public int Integer2;
}
A a = new B();
This will overwrite some unknown part of the stack.
The alternative is for the runtime to prevent this by only writing sizeof(A) bytes to any A variable.
What happens if B overrides a method in A and references its Integer2 field? Either the runtime throws a MemberAccessException, or the method instead accesses some random data on the stack. Neither of these is permissible.
It's perfectly safe to have struct inheritance, so long as you don't use structs polymorphically, or so long as you don't add fields when inheriting. But these aren't terribly useful.
There is a point I would like to correct. Even though the reason structs cannot be inherited is because they live on the stack is the right one, it is at the same a half correct explanation. Structs, like any other value type can live in the stack. Because it will depend on where the variable is declared they will either live in the stack or in the heap. This will be when they are local variables or instance fields respectively.
In saying that, Cecil Has a Name nailed it correctly.
I would like to emphasize this, value types can live on the stack. This doesn't mean they always do so. Local variables, including method parameters, will. All others will not. Nevertheless, it still remains the reason they can't be inherited. :-)
This seems like a very frequent question. I feel like adding that value types are stored "in place" where you declare the variable; apart from implementation details, this means that there is no object header that says something about the object, only the variable knows what kind of data resides there.
Structs do support interfaces, so you can do some polymorphic things that way.
IL is a stack-based language, so calling a method with an argument goes something like this:
Push the argument onto the stack
Call the method.
When the method runs, it pops some bytes off the stack to get its argument. It knows exactly how many bytes to pop off because the argument is either a reference type pointer (always 4 bytes on 32-bit) or it is a value type for which the size is always known exactly.
If it is a reference type pointer then the method looks up the object in the heap and gets its type handle, which points to a method table which handles that particular method for that exact type. If it is a value type, then no lookup to a method table is necessary because value types do not support inheritance, so there is only one possible method/type combination.
If value types supported inheritance then there would be extra overhead in that the particular type of the struct would have to placed on the stack as well as its value, which would mean some sort of method table lookup for the particular concrete instance of the type. This would eliminate the speed and efficiency advantages of value types.
I'm having a problem with BoundingSpheres in XNA. I'm wanting to add a BoundingSphere to a list of BoundingSpheres. At the moment it's along the lines of:
Aircraft(Vector3 pos, float radius, CollisionManager colMan)
{
BoundingSphere sphere = new BoundingSphere(pos, radius);
colMan.AddSphere(sphere)
}
List<BoundingSphere> spheres = new List<BoundingSphere>();
CollisionManager()
{
spheres = new List<BoundingSphere>();
}
AddSphere(BoundingSphere boundingSphere)
{
spheres.Add(boundingSphere);
}
Rather then a reference being added, it seems to be adding the values. I believe this is because boundingSpheres are structs? How can I get round this? I tried the ref keyword, but the values still aren't being updated in the list.
To be straightforawrd, you can't, at least not directly. Structs are value types, and are thus passed and stored by value. Even judicious use of the ref keyword won't get around it because List<T>.Item can't return a reference to a value type.
The work-arounds are to either turn your struct into a class, or embed the stuct inside a class, or, just deal with the fact it's a value type and treat it appropriately (ie, don't try to modify local copies, but replace values in the list when the change). The last option is, imo, the best.
Value types are passed by value (this means that you're getting fresh new copy in the method or in the container) to avoid this you can change your struct to class, add an interface to struct declaration and box your struct to store reference to the interface instead.
But it seems that you're using mutable struct and this is a very dangerous because you can face really dangerous behavior (see mutable structs considered harmful for more details).
You'd have to change the definition of BoundingSphere from a class to a struct. This is impossible since it's defined in an assembly outside of your control.
You can't box the structure, as every time you unbox it, you're going to get a copy of the structure you're holding.
That said, the only way you can do this (and this isn't a good idea, in my opinion) is by creating a class wrapper for the structure, and delegating all of the calls from the properties to the structure internally:
public class BoundingSphereWrapper
{
// Set through constructor.
private readonly BoundingSphere _boundingSphere = ...;
// One of the forwarded calls.
public ContainmentType Contains(BoundingBox box)
{
// Forward the call.
return _boundingSphere.Contains(box);
}
// And so on...
}
Of course, you can't pass these class instances to members that expect a BoundingSphere, and you'd have to try and detect changes (which are near impossible, unless the instances are passed by reference) when you expose the underlying structure.
Namely, though, you don't really want to do this; the designers of the structure probably chose it as a structure for the following reasons:
While mutable (which is a no-no when dealing with structures), the lifetime is intended to be limited
There could be many of these instantiated at the same time, and it's more efficient to do this on the stack than to do it on the heap (that would cause lots of first generation garbage collections, which can definitely have an impact on performance on a gaming platform)
Consider the following C# class:
public class Person
{
public string Name {get;set}
public int Age {get;set}
}
I will only be using this for passing along a couple variables in a function with a single parameter - would using a struct be a better approach?
Edit: I dont care if the values change, they are not supposed to change anyway.
From the bottom of Eric Lippert's excellent "the stack is an implementation detail":
I’d always make the choice of value type vs reference type based on whether the type is semantically representing a value or semantically a reference to something.
That is, how would equality be defined between two Person variables - if they contain the same values, or they are two references to a single instance?
It depends on your expectation of what should happen after you pass in the values.
If you don't care about the changes in the values being retained after the function call finishes, you could make it a struct, but if you want the function which takes a person argument to make changes and the caller should see it, use a class .
Also, if this is part of a domain model / data layer I'd stick with a class.
Its depends upon your requirement. If you dont want to inherit and dont want any modification within the object (since its value type), then you can go ahead with struct.
otherwise class is best in all the way especially to apply inheritance concepts.
may be this is duplicate to: Which is best for data store Struct/Classes?
From MSDN:
A class is a reference type. When an object of the class is created, the variable to which the object is assigned holds only a reference to that memory. When the object reference is assigned to a new variable, the new variable refers to the original object. Changes made through one variable are reflected in the other variable because they both refer to the same data.
A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy.
In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.
my rule of thumb;
Use a class untill you need millions and need a struct to save on storage
Among others, using structs will make this not work;
List[x].Name ="NewName";
My inclination would be to use a simple struct with public fields (not properties). The beautiful thing about such structs is that they all behave identically aside from the names and types of their fields. Given an array MyPeople[] of a struct Person with exposed field Name, one can know that MyPeople[0].Name = "George"; will have no effect upon MyPeople[1].Name. By contrast, if Person were an otherwise-identical class, there would be no such guarantee. Even if Person were a struct with a read-write property Name, one wouldn't know without looking at its definition whether or not the property would actually behave like a struct field, or whether it would access something stored in a class object.
Note that the reasons which might cause one to generally favor properties over fields do not apply to simple structs. If an object Fred holds a field George of a class type, and has exposed to the outside world a reference to the object referred to thereby, the only way Fred can know that George's properties won't change without its knowledge or consent is if the code for class George won't let those properties change without, at minimum, letting Fred know about (in many cases, it's simplest for George to simply promise that it won't let its properties change under any circumstances). By contrast, if Fred holds a field Ronald of an exposed-field struct type, there is no way that any of Ronald's fields will change without Fred's knowledge and consent. Since nobody but Fred can manipulate those fields, and since Fred will know what it requires of the struct, it's simplest to simply have Fred be the one responsible for maintaining any desired invariants.
This question already has answers here:
When should I use a struct rather than a class in C#?
(31 answers)
Closed 7 years ago.
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; }
}
}
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>();
I suppose you could look at When to use struct in C#?
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.
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.
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).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
There are any number of questions here on SO dealing with the differences between Structs and Classes in C#, and when to use one or the other. (The one sentence answer: use structs if you need value semantics.) There are plenty of guidelines out there about how to choose one or the other, most of which boil down to: use a class unless you meet these specific requirements, then use a struct.
This all makes sense to me.
However, I can't seem to find any real-life examples of people using structs in a system. I'm (semi-)new to C#, and I'm having trouble imagining a concrete situation where structs are really the right choice (at least, I haven't run into one yet.)
So, I turn to the SO world-brain. What are some cases where you actually used a struct in a system where a class wouldn't have worked?
Well a class would still work for it, but an example I could think of is something like a Point. Assuming it is an x and y value, you could use a struct.
struct Point {
int x;
int y;
}
In my mind, I would rather have a more simple representation of a pair of integers than to define a use a class with instantiations when the actual entity does not really have much(or any) behavior.
I used a struct to represent a Geolocation
struct LatLng
{
public decimal Lattitude
{
get;
set;
}
public decimal Longitude
{
get;
set;
}
}
this represents a single entity, for instance I can add 2 LatLng's together or perform other operations on this single entity.
MSDN-struct
The struct type is suitable for
representing lightweight objects such
as Point, Rectangle, and Color.
Although it is possible to represent a
point as a class, a struct is more
efficient in some scenarios. For
example, if you declare an array of
1000 Point objects, you will allocate
additional memory for referencing each
object. In this case, the struct is
less expensive.
Also if you look at primitive types Int32,decimal,double..etc you will notice they are all structs, which allows them to be value types whilst allowing them to implement certain crucial interfaces.
Structs are also typically used in graphics/rendering systems. There are many benefits to making points/vectors structs.
Rico Mariani posted an excellent quiz on value based programming. He discussed many reasons to prefer structs in specific situations, and explained it in detail in his quiz results post.
A Money struct is probably one of the most common, however Phone number or Address are also common.
public struct Money
{
public string Currency { get; set; }
public double Amount { get; set; }
}
public struct PhoneNumber
{
public int Extension { get; set; }
public int RegionCode { get; set; }
//... etc.
}
public struct FullName
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
Keep in mind though that in .NET your structs should not be larger in memory footprint than 16 Bytes, because if they get bigger the CLR has to allocate additional memory.
Also because structs 'live' on the stack (and not the heap as reference types do) you might consider using structs if you need to instantiate a lot of the same types of objects.
The quintessential example is the frameworks nullable types, such as int?. These use structs so they retain the value semantics of an int, yet providing a way to make them null without boxing and turning them into reference types.
You would use a struct when you don't want to pass something by reference. Suppose you have a collection of data, or an object that you wish to pass by value (ie, anything you pass it to is working with its own unique copy, not a reference to the original version) then a struct is the right type to use.
They provide a default implementation for Object.GetHashCode(), so you might want to use a struct instead of a class when the object is a simple collection of non-reference types that you want to use as keys to a dictionary.
They are also useful for PInvoke/interop or low-level networking scenarios where you want precise control over the binary layout of a data structure. (go to www.pinvoke.net for lots of interop code that requires structs)
But really, I never use them myself. Don't sweat not using them.
Basically I try to NOT use them. I find they confuse other developers on the team and thus are not worth the effort. I have only found one case to use it, a custom Enum-like type we use a code generator to produce from XML.
The key for me is to define if I want to keep reference to the same object.
Which makes sence when struct is part of another entity, but does entity itself.
In the example above with LatLong that makes perfect sence, for example. You need to copy values from one object to another, not keep referensing the same object.
I often use structs to represent a domain model value type that might be represented as an enum, but needs an arbitrary unlimited number of discrete values, or I want it to have additional behavior (methods) that you cannot add to an enum... For example, in a recent project many data elements were associated with a specific calendar Month rather than with a date. So I created a CalendarMonth struct that had methods:
static CalendarMonth Parse(DateTime inValue);
static CalendarMonth Parse(string inValue);
and TryParse( ) method,
static bool TryParse(string inValue, out CalendarMonth outVal);
And Properties
int Month { get; set; }
int Year { get; set; }
DateTime StartMonthLocal { get; set; }
DateTime StartMonthUTC{ get; set; }
DateTime EndMonthLocal { get; set; }
DateTime EndMonthUTC { get; set; }
etc.
im not usually concerned with 'data-density' in my business apps. I will typically always use a class unless I specifically want value semantics
this means that i am forseeing a situation where i want to compare two of these things and i want them to show up as the same if they have the same value. With classes this is actually more work because i need to override ==, !=, Equals, and GetHashcode, which even if resharper does it for me, is extra needless code.
So in my mind, always use classes unless you know that you want these things to be compared by value(in this case component value)
So I take it you've never used DateTime (a struct).
I can't believe no one has mentioned XNA: in XNA, almost everything is a struct. So when you do
Matrix rotation = Matrix.CreateRotationZ(Math.PiOver2);
You are really creating a value-type.
This is because, unlike in applications programming, a stall of a few milliseconds while the garbage collector runs is not acceptable (we only get 16.6 ms to render the entire frame!), so we have to avoid allocations as much as possible so the GC doesn't have to run as much.
This is especially true on the XBox 360, where the GC is nowhere near the quality it is on the PC - even an average of one allocation per frame can kill performance!
I have been working in financial institutions where large scale caching and latency requirements was achieved using structs. Basically structs can spare the garbage collector of A LOT of work.
See these examples:
http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/
http://00sharp.wordpress.com/2013/07/04/a-case-for-the-structpart-2/
Basically, I use Structs for modeling geometric and mathematical data, or when I want a Value-based data-structure.
The only time I've ever used a struct was when I was building a Fraction struct:
public struct Fraction
{
public int Numerator {get;set;}
public int Denominator {get; set;}
//it then had a bunch of Fraction methods like Reduce, Add, Subtract etc...
}
I felt that it represents a value, just like the built in value types, and therefore coding against it would feel more natural if it behaved like a value type.
I think the .Net Framework is quite real life. See the list under "Structures":
System Namespace
In some performance-critical situations, a struct (a value type and thus allocated from the stack) can be better than a class (a reference type and thus allocated from the heap). Joe Duffy's blog post "A single-word reader/writer spin lock" shows a real-life application of this.
One I've created in the past is StorageCapacity. It represented 0 bytes to N exabytes (could have gone higher to the yottabyte, but exa seemed enough at the time). The struct made sense since I worked for a storage management company. You would think it was fairly simple: a struct with a StorageUnit (enum) and a Quantity (I used decimal). But when you add in conversions, operators, and classes to support formatting, parsing, etc. it adds up.
The abstraction was useful to enable you to take any StorageCapacity and represent it as bytes, kilobytes, etc. without having to multiply or divide by 1024 many times.
I have given my reasons for using structs already elsewhere (When to use struct in C#), and I have used structs for these reasons in real-life projects:
I would choose to use structs for performance reasons if I needed to store a large number of the same item type in an array, which may happen in image processing.
One needs to use structs for passing structured data between C# and C++.
Unless I have a very good reason to use them I try to avoid them.
I know that some people like to use them for implementing value semantics but I find that this behavior is so different from the "normal" assignment behavior of classes (in C#) that one finds oneself running into difficult to trace bugs because one did not remember that the object one was assigning from or to had this behavior because it was implemented as a struct instead of a class. (It has happened to me more than once, so I give this warning since I actually have been burned by the injudicuous use of C# structs.)
I'm not sure how much use this is, but I discovered today that whilst you cannot have instance field intializers in structs, you can in classes.
Hence the following code will give compilation errors, but if you change the "struct" to "class" it compiles.
public struct ServiceType
{
public bool backEnd { get; set; }
public bool frontEnd { get; set; }
public string[] backEndServices = { "Service1", "Service2" };
public string[] frontEndServices = { "Service3", "Service4" };
}
A struct in C# is at its heart nothing more nor less than a bunch of variables stuck together with duct tape. If one wants each variable of a particular type to represent a bunch of independent but related variables (such as the coordinates of a point) stuck together with duct tape, it's often better to use an exposed-field struct than a class, regardless of whether "bunch" means two or twenty. Note that although Microsoft's struct-versus-class advice is fine for data types which encapsulate a single value, it should be considered inapplicable for types whose purpose is to encapsulate independent but related values. The greater the extent to which the variables are independent, the greater the advantages of using an exposed-field struct.
If one wishes to use a class to encapsulate a bunch of independent variables, there are two ways one can do it, neither of which is terribly convenient. One may use an immutable class, in which case any non-null storage location of that class type will encapsulate the values held by the instance identified thereby, and one storage location may be copied to another to make the new one encapsulate those same values. Unfortunately, changing one of the values encapsulated by a storage location will generally require constructing a new instance which is just like the old one except with that value changed. For example, if one has a variable pt of type Immutable3dPoint and one wished to increase pt.X by one, one would have to do something like: pt = new Immutable3dPoint(pt.X+1, pt.Y, pt.Z); Perhaps tolerable if the type only encapsulates three values, but pretty annoying if there very many.
The other class-based approach is to use a mutable class; this generally requires that one ensure that every storage location of the class type holds the only reference anywhere in the universe to an instance of that class. When a storage location is created, one must construct a new instance and store a reference there. If one wishes to copy the values from storage location P to storage location Q, to another, one must copy all the fields or properties from one instance to the other (perhaps by having the type implement a CopyFrom method, and saying Q.CopyFrom(P);. Note that if one instead says Q=P; that may seem to work, but future attempts to modify P will also modify Q and vice versa. Mutable classes may work, and they can at times be efficient, but it's very easy to mess things up.
Exposed-field structures combine the convenient value-copy semantics of immutable classes with the convenient piecewise modifications allowed by mutable classes. Large structures are slower to copy than are references to immutable objects, but the cost of modifying part of an exposed-field structure depends only upon the extent of the modification, rather than upon the overall structure size. By contrast, the cost of changing one piece of data encapsulated in an immutable class type will be proportional to the total class size.