1

Consider the following C# class:

public class Person
{
    public string Name {get;set}
    public int Age {get;set}
}

I will only be using this for passing along a couple variables in a function with a single parameter - would using a struct be a better approach?

Edit: I dont care if the values change, they are not supposed to change anyway.

Jeff
  • 12,085
  • 12
  • 82
  • 152

6 Answers6

2

From the bottom of Eric Lippert's excellent "the stack is an implementation detail":

I’d always make the choice of value type vs reference type based on whether the type is semantically representing a value or semantically a reference to something.

That is, how would equality be defined between two Person variables - if they contain the same values, or they are two references to a single instance?

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • So, I should pick a struct, based on the fact that I am just grouping some values together? – Jeff Sep 11 '12 at 07:33
1

Its depends upon your requirement. If you dont want to inherit and dont want any modification within the object (since its value type), then you can go ahead with struct.

otherwise class is best in all the way especially to apply inheritance concepts.

may be this is duplicate to: Which is best for data store Struct/Classes?

Community
  • 1
  • 1
VIRA
  • 1,454
  • 1
  • 16
  • 25
1

It depends on your expectation of what should happen after you pass in the values. If you don't care about the changes in the values being retained after the function call finishes, you could make it a struct, but if you want the function which takes a person argument to make changes and the caller should see it, use a class .

Also, if this is part of a domain model / data layer I'd stick with a class.

Krishna
  • 2,997
  • 1
  • 23
  • 31
  • Copying from my last comment: So, I should pick a struct, based on the fact that I am just grouping some values together? – Jeff Sep 11 '12 at 07:50
  • Perhaps. I don't see any reason why you couldn't use a struct. Of course, you may also have to think about identity. If two instances of the Person have the same values, does it mean they are the same person? – Krishna Sep 11 '12 at 07:56
  • Equality is not required in this case - I am merely passing along values to be transformed with XML :) – Jeff Sep 11 '12 at 08:01
  • If you use a ref struct you will see the changes, so that's not really a reason to base a choice on? – IvoTops Sep 11 '12 at 08:35
1

From MSDN:

A class is a reference type. When an object of the class is created, the variable to which the object is assigned holds only a reference to that memory. When the object reference is assigned to a new variable, the new variable refers to the original object. Changes made through one variable are reflected in the other variable because they both refer to the same data.

A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy.

In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.

Community
  • 1
  • 1
cuongle
  • 74,024
  • 28
  • 151
  • 206
1

my rule of thumb;

  • Use a class untill you need millions and need a struct to save on storage

Among others, using structs will make this not work;

  • List[x].Name ="NewName";
IvoTops
  • 3,463
  • 17
  • 18
  • No, but if one uses a struct, `var temp=List[x]; temp.Name="NewName"; List[x]=temp;` will work and have the expected effects. If one uses a mutable class, `List[x].Name="NewName";` will compile and will do something, but one may have to examine a lot of code in order to determine its full effect (in particular, what other references to the modified object exist). – supercat Sep 11 '12 at 20:18
  • the temp method works, but is ugly. And the code shown will compile, but just not do what you would expect it to do. – IvoTops Sep 12 '12 at 09:43
0

My inclination would be to use a simple struct with public fields (not properties). The beautiful thing about such structs is that they all behave identically aside from the names and types of their fields. Given an array MyPeople[] of a struct Person with exposed field Name, one can know that MyPeople[0].Name = "George"; will have no effect upon MyPeople[1].Name. By contrast, if Person were an otherwise-identical class, there would be no such guarantee. Even if Person were a struct with a read-write property Name, one wouldn't know without looking at its definition whether or not the property would actually behave like a struct field, or whether it would access something stored in a class object.

Note that the reasons which might cause one to generally favor properties over fields do not apply to simple structs. If an object Fred holds a field George of a class type, and has exposed to the outside world a reference to the object referred to thereby, the only way Fred can know that George's properties won't change without its knowledge or consent is if the code for class George won't let those properties change without, at minimum, letting Fred know about (in many cases, it's simplest for George to simply promise that it won't let its properties change under any circumstances). By contrast, if Fred holds a field Ronald of an exposed-field struct type, there is no way that any of Ronald's fields will change without Fred's knowledge and consent. Since nobody but Fred can manipulate those fields, and since Fred will know what it requires of the struct, it's simplest to simply have Fred be the one responsible for maintaining any desired invariants.

supercat
  • 77,689
  • 9
  • 166
  • 211