Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing reference types in Struct

Tags:

c#

struct

Say I had a very simple struct in c#

   public struct foo{
   public  int a{get;set;}
   public  int b{get;set;}
   public  int c{get;set;}
   public  int d{get;set;}
   public  string hello {get;set;}
   }

I take it the above is more 'efficient' than using a class?

At what point, if I continued to add string properties, would it be time to convert the struct to a class?

Edit: I had planned to pass this struct around a GDI - centric application. I had always assumed structs were more performant when dealing with mainly value types.

like image 641
maxp Avatar asked Feb 16 '12 15:02

maxp


2 Answers

I take it the above is more 'efficient' than using a class?

Absolutely not. That is a terrible struct. Structs should be small; no more than, say, four times the size of a reference; your struct is the size of five references on an 32 bit machine. Structs should represent values; this does not appear to represent any value. Structs should be immutable; this is chock full of mutability.

At what point, if I continued to add string properties, would it be time to convert the struct to a class?

The point to convert this structure to a class was the moment you created it. It should never have been a struct in the first place. Your default assumption should be that classes are good enough; only go to a struct when you have evidence that doing so solves a problem that you actually have.

I had planned to pass this struct around a GDI - centric application. I had always assumed structs were more performant when dealing with mainly value types.

Structs are more efficient than classes in a very small number of cases: when they are small, immutable, represent values, and are composed of other values, like integers. In other cases they are less efficient: because structs are copied by value, large structs can be much slower to use than references. Because structs are copied by value, mutable structs lead to bugs because you mutate copies when you think you are mutating variables. Because structs are copied by value, they should have the semantics of values, not references. And because structs that contain only other structs can be skipped by the garbage collector entirely, structs are only more efficient for cleanup purposes when they contain no references.

In any event, the way you tell if something is more efficient is try it both ways and measure its performance against your performance goals. Use science. Set a goal and measure it. Using structs "because I assume they are more efficient" is making technical decisions on the basis of hearsay. Measure, and then you'll know what is more efficient.

like image 77
Eric Lippert Avatar answered Oct 02 '22 15:10

Eric Lippert


If you need the enhanced capabilities that a class offers, such as inheritance, then switch. If not, a struct can be a bit "lighter," but unless you anticipate some performance issues, such as garbage collection inside of a tight loop with a LOT of iterations, the necessity to pass structs around with ref whenever you want a method to make modifications, etc can create unnecessary work. (Though, in that example, destroying a struct that has reference-type properties also causes GC).

The practical upshot being: whether to use a struct or a class is a matter of your use case, not the number of properties that you have.

For a good explanation of the differences between and relative strengths and weakness of classes and structs, see this MSDN article.

For Eric Lippert's excellent note on garbage collection, structs and classes, see his response to this question.

like image 34
3Dave Avatar answered Oct 02 '22 16:10

3Dave