8

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?

lak-b
  • 2,115
  • 4
  • 18
  • 30
  • Not an answer to your question but if you do work with structs, avoid mutable structs: http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil – Meta-Knight Dec 28 '09 at 18:50
  • The answer is that they are value types stored on the stack as opposed to reference types stored in the heap. So the answer is only the answer you say you don't want. – CaseyB Dec 28 '09 at 19:24
  • if you know that "it is in the stack" then you should know what they are for. – Stan R. Dec 28 '09 at 19:31
  • my comment was sarcastic and implied that just because he knows "its in the stack" he should learn what that *really* means, however your comments are really interesting.. – Stan R. Dec 28 '09 at 20:22
  • 2
    +1: most be a good question since at least half of the submitted answers have multiple downvotes ;) – Juliet Dec 28 '09 at 20:22
  • Stan R, on second thought, you have a point. Stack storage is the defacto implementation of value types, and for a reason. It's a confusing enough topic though. OP can use some help. – Stefan Monov Dec 28 '09 at 23:08
  • Note: http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx – RCIX Dec 29 '09 at 00:28
  • dupe: http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net – RCIX Dec 29 '09 at 00:29

10 Answers10

22

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.

jason
  • 236,483
  • 35
  • 423
  • 525
  • 5
    This is definitely right (as was your excellent comment elsewhere), but probably not helpful: I think most people that would ask this question obviously don't understand the differences between reference-type and value-type semantics. – Jeff Sternal Dec 28 '09 at 19:04
  • 2
    But the question was "struct - what is it for?" not "What is the difference between a value type and a reference type." If the poster wants to know that then he should ask it here in a comment, or even better, open a new question. I'm sure many would be happy to provide an answer to that question too. – jason Dec 28 '09 at 19:08
  • 3
    This answer is correct of course, but it wouldve been nicer if you explained those differences..of which there are a few. – Stan R. Dec 28 '09 at 19:28
  • @Stan R.: As I mentioned in my answer to Jeff Sternal, I believe that is better addressed in a separate question. structs and classes are implementations of value-type and refernece-type semantic types respectively; they do not define the concept. – jason Dec 28 '09 at 19:33
  • 1
    @Jason. I agree Jason, but we can't really nitpick every question like that. If we did we'd never have an answer. Although there are many SO questions that answer this exact question, and I have no idea why this hasn't been closed. – Stan R. Dec 28 '09 at 20:23
10

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.
Community
  • 1
  • 1
Ta01
  • 31,040
  • 13
  • 70
  • 99
  • 6
    I hate that guide because it talks about performance concerns and the struct/stack class/heap implementation-detail nonsense. Those concerns are in a distant second place to the main concern: semantics. – jason Dec 28 '09 at 19:02
  • @Jason: There are three types of entities: mutable value types, mutable reference types, and immutable types. The only structs which are semantically different from reference types are mutable ones. I for one think that mutable value types are at times useful, and regard most of the complaints about them as really being complaints about limitations in how .net handles them (e.g. the inability specify a custom boxing operator), but some people hate them. – supercat Mar 03 '11 at 17:40
6

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.

Stefan Monov
  • 11,332
  • 10
  • 63
  • 120
  • The best way to answer the "struct vs class" question is often to ask your "What should ..." question, though I'd replace "a.Mutate() with "a.x=5"; I'd also note that vb.net and C# have some annoying limitations that may require one to make something use class even though something should have value semantics (it's almost impossible, for example, to make a struct that contains an array behave like a value type). – supercat Jan 20 '11 at 20:22
4

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.

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
  • OK. But, if the reason of using struct is only that memory optimization, so... Are you using reflection? Heavy SQL queries? LINQ? Any of these things overlap such optimization with struct, I think. – lak-b Dec 28 '09 at 18:51
  • 1
    structs are not always allocated on the stack. And the primary reasons for choosing structs have nothing to do with the implementation detail of being allocated on the stack. – jason Dec 28 '09 at 18:52
  • A little thought about the explanation you gave: http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx – Pedro Dec 28 '09 at 18:52
  • I'm not saying that structs are only useful for mem optimization. A struct is an ideal tool to create a value type, that's what I'm saying. Jason: how do you -in .NET- create a struct that is allocated on the heap ? – Frederik Gheysels Dec 28 '09 at 18:53
  • @Frederik Gheysels: Boxed structs, structs that are members of classes and structs that are hoisted because it's an outer variable in an anonymous method or an iterator block are all allocated on the heap. – jason Dec 28 '09 at 18:59
  • @Pedro: Sorry to say, but you should read my post better, and re-read Eric Lippert's article. In that article, Eric is saying that 'a value type is not always allocated on the stack'. Which is correct, since you can implement a value type using a class as well (System.String, for instance). However, I said that a struct is allocated on the stack, and that a struct is a value type. I did not say that a 'value' type is allocated on the stack. It's like I'm saying: 'A pinguin is a bird, and a pinguin cannot fly', and you conclude then that I've said that 'birds cannot fly'. – Frederik Gheysels Dec 28 '09 at 19:02
4

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.

Stan R.
  • 15,757
  • 4
  • 50
  • 58
  • would be nice if downvoters explained what the downvotes are for? – Stan R. Dec 28 '09 at 20:09
  • Structs are not immutable (but I didn't downvote). See http://stackoverflow.com/questions/608542/immutability-of-structs – Brian Rasmussen Dec 29 '09 at 00:00
  • 1
    @Brian. thanks, i'd rather someone pointed that out to me rather thant downvoted. What I meant by immutable was that the variable that is holding the struct is immutable. Obviously a struct is not read-only once you create it, which of course by definition is mutable..unless you make an immutable struct(which I think is good practice) – Stan R. Dec 29 '09 at 00:38
3

Youcan use structs when you want a "class" with value (rather than reference) semantics.

  • Say you want a Complex type for storing complex numbers. Complex type should behave exactly like int - as both are some kinds of numbers. You cannot declare Point as class, because classes are reference types. Expression "Complex a = b" should assign "a" **value** of b, not **reference** to it. – el.pescado - нет войне Dec 28 '09 at 20:58
3

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.

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

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.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • But may be I missed something? I can code without enums, but it will be not so comfortable, I guess. – lak-b Dec 28 '09 at 18:46
  • stuct and enum are not the same thing. Why would you even mention them? – Erik Funkenbusch Dec 29 '09 at 00:51
  • @Mystere Man he was using enums as a counter-example to your logic. Just because he doesn't know what a struct is for doesn't mean that the knowledge would not be useful to him. Similarly, he could get by without understanding enums, but that knowledge would make his life easier. – Ross Dec 29 '09 at 01:51
  • I didn't say the knowledge would not be useful, my point is that he's probably not at a level of understanding in which the difference between a struct and a class are important to his decisions. I have very seldom needed structs in my programming even with the knowledge of their difference. – Erik Funkenbusch Dec 29 '09 at 04:33
  • MystereMan, I respectfully but strongly disagree. if you don't know the relationship between structs and enums then perhaps you "don't" need to be using either... Clearly you don't appreciate where when and how structs are useful, or you wouldn't be so negative about them. – Charles Bretana Oct 12 '11 at 19:31
  • @CharlesBretana - I think you misunderstood. I wasn't being negative about structs or enums at all. Perhaps you should re-read. – Erik Funkenbusch Oct 12 '11 at 21:23
1

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.

JimDaniel
  • 12,513
  • 8
  • 61
  • 67
  • Thank for this :) But, for now I think, such optimizations are useless: who really cares about such little things while using reflection and large SQL queries (3 joins by ORM, ha-ha :) I see only one useful thing - struct can't be NULL. – lak-b Dec 28 '09 at 18:58
  • 1
    It's also a matter choosing the right tool for the job. When I see a struct I know immediately what to expect from it. For something like my example a simple structure just feels more correct. – JimDaniel Dec 28 '09 at 19:09
0

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.