views:

1910

answers:

19

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?

+3  A: 

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.

Mystere Man
+12  A: 

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.

ghills
I find it interesting that you chose to use x and y for your point... What about z?
RSolberg
Oh yeah +1 for making it simple...
RSolberg
so your x and y are private variables? :)
Stan R.
ah yes, my C programming sometimes leak through...
ghills
Stan: structs and their members are public by default.
Costa Rica Dev
you sure about that Costa Rica Dev? because not in C#...which is what this question was tagged as...
Stan R.
You're right. I so seldom use structs, i confuse C# and C++.
Costa Rica Dev
@Stan http://msdn.microsoft.com/en-us/library/system.drawing.point.aspx
Sandor Davidhazi
@Sandor, what exactly is your "point" ??
Stan R.
+11  A: 

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.
Downvoated, Most of these examples don't explain WHY you choose a struct over a class.
Costa Rica Dev
umm..it says it right there in the answer "this represents a single entity, for instance I can add 2 LatLng's together or perform other operations on this single entity." Also, read the question.."However, I can't seem to find any real-life examples of people using structs in a system."
Stan R.
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
+1 As I used a struct for the exact same thing!
Dan Diplo
@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.
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
@Jared, well yes that is straight out of MSDN :)
Stan R.
What is Longitute?
AndyMcKenna
Didn't know this was aslo an English school. :P
Stan R.
What is Lattitude? ;)
Guffa
@Guffa...lol i hate all of you !!! spelling police !
Stan R.
+6  A: 

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.

Stephan
Wow, you really got that wrong. It's 16 BYTES, not 16 kilobytes... ;)
Guffa
Wow, you're right :) thanks for that!
Stephan
I edited the answer to reflect your correction Guffa.
swilliams
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
@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
+1 for Guffa's comment. Structs + strings = confusimojo.
jrista
@Stephan, don't use double to represent a monetary amount, use decimal instead. See MSDN on decimal.
Ash
+8  A: 

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
Love that link. V Useful
zebrabox
+1  A: 

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
A: 

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

Moayad Mardini
+2  A: 

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
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
A: 

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
+1  A: 

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
A: 

I was under the impression that structs were more light-weight than classes. So for example the difference between

public class Point
{
    public int x;
    public int y;
}

and

public struct Point
{
    public int x;
    public int y;
}

is that you can construct a million Point structs 28 percent faster than a million Point classes. This is because there is no default constructor hidden in a struct.

I got the 28 percent from a bench test I just put together - so that may or may not be dead-on accurate.

DataDink
I agree with your point on performance of structs vs classes. However, the reason you gave to explain it is incorrect. Structs have implicit paramerless constructors. According to [C# language specification](http://msdn.microsoft.com/en-us/library/ms228593.aspx) on section 11.3.4, "every struct implicitly has a parameterless instance constructor which always returns the value that results from setting all value type fields to their default value and all reference type fields to null."
Carlos Loth
A: 

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
+1  A: 

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
A: 

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

System Namespace

Sandor Davidhazi
A: 

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
A: 

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
A: 

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

ILoveFortran
A: 

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

FlySwat
A: 

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