tags:

views:

593

answers:

10

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?

+5  A: 

MSDN provdies a guide : Choosing Between Classes and Structures

RandomNoob
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
@Jason, I agree.
RandomNoob
+3  A: 

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

el.pescado
Please, examples?
lak-b
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
+2  A: 

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.

Mystere Man
But may be I missed something? I can code without enums, but it will be not so comfortable, I guess.
lak-b
stuct and enum are not the same thing. Why would you even mention them?
Mystere Man
@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
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.
Mystere Man
+4  A: 

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
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
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
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
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
Frederik, read Eric Lippert's explanation on the link above.
Pedro
@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
@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
+1  A: 

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

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
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
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
+1 Great answer. Succinct and absolutely correct.
Byron Whitlock
This answer is correct of course, but it wouldve been nicer if you explained those differences..of which there are a few.
Stan R.
@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
@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.
+3  A: 

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.
would be nice if downvoters explained what the downvotes are for?
Stan R.
Structs are not immutable (but I didn't downvote). See http://stackoverflow.com/questions/608542/immutability-of-structs
Brian Rasmussen
@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.
+2  A: 

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

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

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.

millky