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
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.
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.
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.
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?
Use the principle of least surprise here.
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.
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.