42

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?

Jason Down
  • 21,731
  • 12
  • 83
  • 117
Electrons_Ahoy
  • 36,743
  • 36
  • 104
  • 127

21 Answers21

21

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.

RSolberg
  • 26,821
  • 23
  • 116
  • 160
Gavin H
  • 10,274
  • 3
  • 35
  • 42
  • Oh yeah +1 for making it simple... – RSolberg Aug 28 '09 at 20:53
  • 1
    so your x and y are private variables? :) – Stan R. Aug 28 '09 at 20:55
  • ah yes, my C programming sometimes leak through... – Gavin H Aug 28 '09 at 20:55
  • 2
    Stan: structs and their members are public by default. – Costa Rica Dev Aug 28 '09 at 20:56
  • 12
    you sure about that Costa Rica Dev? because not in C#...which is what this question was tagged as... – Stan R. Aug 28 '09 at 20:57
  • You're right. I so seldom use structs, i confuse C# and C++. – Costa Rica Dev Aug 28 '09 at 21:03
  • @Stan http://msdn.microsoft.com/en-us/library/system.drawing.point.aspx – Sandor Davidhazi Aug 28 '09 at 22:35
  • 1
    @Sandor, what exactly is your "point" ?? – Stan R. Aug 29 '09 at 05:31
  • A two-dimensional or three-dimensional `Point` is a perfect example of when an exposed-field struct is appropriate (note that in C# one must explicitly declare fields `public` to make them so). Note that if one has two fields of a struct type `Point`, the fields together hold four integer values. By contrast, if two fields hold references of a mutable point class type, the fields encapsulate object *identities* (which might refer to the same object, or objects that happen to hold the same values). If an object isn't supposed to encapsulate identity, a struct may be better. – supercat Jul 05 '13 at 17:22
17

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.

Stan R.
  • 15,757
  • 4
  • 50
  • 58
  • 2
    Downvoated, Most of these examples don't explain WHY you choose a struct over a class. – Costa Rica Dev Aug 28 '09 at 20:54
  • 2
    Simply aggregating individual entities is not a valid reason to choose a struct over a class. You can use both for that, so I don't see how that answers the question. And yes, he did ask for examples, but an example should explain why you're using a struct and not a class. – Costa Rica Dev Aug 28 '09 at 20:59
  • +1 As I used a struct for the exact same thing! – Dan Diplo Aug 28 '09 at 21:02
  • @Costa Rica Dev, the OP asked a question to see examples of a struct. We showed it to him. There are plenty of SO questions that explain when and why to use a struct. In my case I used a struct because it holds small information that can represent a single small entity(which I mentioned). – Stan R. Aug 28 '09 at 21:04
  • A better explanation would suggest that when you pack unboxed structs in an array, you save a lot memory of overhead not having extra pointers (4 bytes (32 bit pointers) or 8 bytes (64 bit pointers) per LatLng. Compared to the 128 bit decimal struct (so 256 bits or 32 bytes per LatLng you are saving 12.5%-25% overhead, not counting the speed increase of not having to dereference LatLngs and put them in and out of the heap, and the speedups of being able to pass LatLngs on the stack. – Jared Updike Aug 28 '09 at 21:06
  • @Jared, well yes that is straight out of MSDN :) – Stan R. Aug 28 '09 at 21:10
  • 1
    Didn't know this was aslo an English school. :P – Stan R. Aug 28 '09 at 21:26
  • @CostaRicaDev: An exposed-field structure is semantically equivalent to the combination of fields contained therein, except that in addition to using the parts of the structure piecemeal one may also use the whole thing or pass the whole thing as a `ref` parameter. If what one wants is to join together a collection of independent but related values (e.g. the coordinates of a point) an exposed-field struct encapsulates that concept perfectly. – supercat Jul 05 '13 at 17:15
13

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.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Love that link. V Useful – zebrabox Aug 28 '09 at 21:00
  • I like that link, though I'd suggest that all the "rules" violations could be fixed by adding one rule, basically saying that if one wants something that will simply behave like a group of related but independent variables bound together with duct tape, won't need any other sort of behavior, and doesn't want any concept of identity, one should generally use a struct, other "rules" notwithstanding. – supercat Sep 23 '13 at 22:51
7

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.

swilliams
  • 48,060
  • 27
  • 100
  • 130
Stephanvs
  • 723
  • 7
  • 19
  • 4
    Wow, you really got that wrong. It's 16 BYTES, not 16 kilobytes... ;) – Guffa Aug 28 '09 at 20:56
  • I edited the answer to reflect your correction Guffa. – swilliams Aug 28 '09 at 21:07
  • The FullName struct kinda puzzles me as if 16 (which I thought it was 32 bytes max for a struct) is the suggested limit thats a very small First, Middle and Last name. Maybe its just me being nit-picky. – CmdrTallen Aug 28 '09 at 21:15
  • 7
    @CmdrTallen: When you put a reference type like as string in a struct, it's the reference that is stored in the struct, not the object itself. On a 32 bit system the FullName struct is 12 bytes. – Guffa Aug 28 '09 at 21:35
  • +1 for Guffa's comment. Structs + strings = confusimojo. – jrista Aug 28 '09 at 22:16
  • 1
    @Stephan, don't use double to represent a monetary amount, use decimal instead. See MSDN on decimal. – Ash Aug 29 '09 at 01:29
  • @stephan..structs live on the stack is a myth http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx – Myles McDonnell Dec 24 '11 at 18:44
5

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.

Jason Down
  • 21,731
  • 12
  • 83
  • 117
Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • I'm not sure nullable types are that great an example. They should generally be avoided in cases where speed is important, and if `Nullable` were a reference type which simply contained a single field of type `T` it may in some cases be slower than a `Nullable` structure but it wouldn't have the weird semantics that arise from the fact that an empty-valued `Nullable` isn't a null reference but it boxes like one. – supercat Jul 08 '13 at 15:18
3

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.

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
  • I actually just discovered the GetHashCode() difference in some code I've been working on - very cool! I almost feel like this is worthy of a question all on it's own (for reference purposes). – Sam Schutte Nov 05 '09 at 15:23
2

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.

csharptest.net
  • 62,602
  • 11
  • 71
  • 89
1

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.

Maxim Alexeyev
  • 1,021
  • 11
  • 24
1

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.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
1

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)

LoveMeSomeCode
  • 3,888
  • 8
  • 34
  • 48
1

So I take it you've never used DateTime (a struct).

FlySwat
  • 172,459
  • 74
  • 246
  • 311
1

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/

Rabbit
  • 1,741
  • 2
  • 18
  • 27
1

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!

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
0

Basically, I use Structs for modeling geometric and mathematical data, or when I want a Value-based data-structure.

Moayad Mardini
  • 7,271
  • 5
  • 41
  • 58
0

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.

BFree
  • 102,548
  • 21
  • 159
  • 201
0

I think the .Net Framework is quite real life. See the list under "Structures":

System Namespace

Sandor Davidhazi
  • 888
  • 1
  • 9
  • 20
0

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.

bobbymcr
  • 23,769
  • 3
  • 56
  • 67
0

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.

Kit
  • 20,354
  • 4
  • 60
  • 103
0

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.)

Community
  • 1
  • 1
ILoveFortran
  • 3,441
  • 1
  • 21
  • 19
  • Some people complain that value semantics are confusing, but I'm curious how such people avoid being confused by the fact that a class reference may be used to encapsulate identity, mutable state, both, or neither, and the effect of copying a reference will depend upon what is encapsulated thereby. Given a `SomeClass[100]`, there are at least three different approaches that may be needed to copy the state encapsulated by element 3 to element 4. How should one know which one to use in each situation, short of examining all the other code that uses the array? – supercat Sep 23 '13 at 23:04
0

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" };
    }
Talvalin
  • 7,789
  • 2
  • 30
  • 40
0

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.

supercat
  • 77,689
  • 9
  • 166
  • 211