Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C#, are the values in a List<struct> boxed?

Tags:

c#

generics

Suppose I declare a generic List containing values of a struct type:

struct MyStruct {     public MyStruct(int val1, decimal val2) : this() {         Val1 = val1;         Val2 = val2;     }     public int Val1 {get; private set;}     public decimal Val2 {get; private set;} }  List<MyStruct> list; 

Does the List<> store each individual value as a boxed struct, allocated individually on the heap? Or is it smarter than that?

like image 813
Roman Starkov Avatar asked Feb 18 '09 07:02

Roman Starkov


People also ask

What does |= mean in C?

The ' |= ' symbol is the bitwise OR assignment operator.

What is '~' in C programming?

In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...

What is an operator in C?

C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.

What is the use of in C?

In C/C++, the # sign marks preprocessor directives. If you're not familiar with the preprocessor, it works as part of the compilation process, handling includes, macros, and more.


2 Answers

It isn't boxed, but the data will be a copy of the original, and every time you get the data out, it will copy again. This tends to make it easy to lose changes. As such, you should aim to not write mutable structs. Unless MyStruct actually represents a unit-of-measure (or similar), make it a class. And if it is a measure, make it immutable (no public settable members).

And either way, don't expose fields! Use properties ;-p

For example:

struct MyStruct {     public MyStruct(int val1, decimal val2) {         this.val1 = val1;         this.val2 = val2;     }     private readonly int val1;     private readonly decimal val2;     public int Val1 {get {return val1;}}     public decimal Val2 {get {return val2;}} } 

Or alternatively (C# 3.0):

struct MyStruct {     public MyStruct(int val1, decimal val2) : this() {         Val1 = val1;         Val2 = val2;     }     public int Val1 {get; private set;}     public decimal Val2 {get; private set;} } 
like image 31
Marc Gravell Avatar answered Sep 28 '22 17:09

Marc Gravell


There is no boxing.

"No, there will be no boxing. That was one of the main design goals of Generics."

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/359cf58a-f53d-478e-bc31-1507e77c9454/

"If a value type is used for type T, the compiler generates an implementation of the List<T> class specifically for that value type. That means a list element of a List<T> object does not have to be boxed before the element can be used, and after about 500 list elements are created the memory saved not boxing list elements is greater than the memory used to generate the class implementation."

http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

like image 99
ajma Avatar answered Sep 28 '22 15:09

ajma