Take the 2-minute tour ×

I have a struct which I put in a List<T>, I want to edit some value in that struct at a specific position. Is this at all possible without making a copy of the struct, editing the copy, and replacing the entry in the List?

share|improve this question
That's the main difference of struct from class. So consider to use classes instead. –  abatishchev Nov 21 '12 at 1:07
I've removed "immutable" from title as it did not make not much sense in sentence "immutable changes"... @reza please check if title reflects your question, rollback edit otherwise. –  Alexei Levenkov Nov 21 '12 at 1:28
all good........ –  reza Nov 21 '12 at 1:40
add comment

3 Answers

up vote 2 down vote accepted

No, to be able to do it you need reference to element of inner array which is not provided by List/IList.

You can do that with unsafe code and arrays if you have to.

share|improve this answer
+1: I missed that...could you, please, explain in greater detail, why is that so. What does the List<T> return by element index? –  horgh Nov 21 '12 at 1:35
from my understanding, it is a copy of the contents. it is treated like an integer. not sure why that is advantageous or why it works that way. –  reza Nov 21 '12 at 1:42
@KonstantinVasilcov, yes what reza said. struct in C# are value types and always copy whole content - see Jon's yoda.arachsys.com/csharp/references.html article about struct vs class. –  Alexei Levenkov Nov 21 '12 at 1:53
@AlexeiLevenkov why then the code I posted in my answer does the trick? –  horgh Nov 21 '12 at 1:55
@reza, note that C++ behave very similar way (bitwise copy by default), the difference is that you usually have versions of most methods with "by reference" arguments/results. –  Alexei Levenkov Nov 21 '12 at 1:56
show 3 more comments

From J.Richter's "CLR via C#", 3rd edition:

Value types should be immutable: that is, they should not define any members that modify any of the type’s instance fields. In fact, I recommended that value types have their fields marked as readonly so that the compiler will issue errors should you accidentally write a method that attempts to modify a field.


Just keep in mind that value types and reference types have very different behaviors depending on how they’re used.

Consider this code:

public interface IChangeStruct
    int Value { get; }
    void Change(int value);

public struct MyStruct : IChangeStruct
    int value;

    public MyStruct(int _value)
        value = _value;

    public int Value
            return value;

    public void Change(int value)
        this.value = value;

and it's usage:

static void Main(string[] args)
    MyStruct[] l = new MyStruct[]
            new MyStruct(0)


The output is:

0 10

So it does what you need.

However the same won't work for List<T>. I guess by the reason, mentioned by Alexei Levenkov. So, I would strongly recommend you to change struct to class if the type in question is not immutable per instance.

share|improve this answer
This is useful... but not directly answering the question... I think it was covered enough in reza's previous question - stackoverflow.com/questions/13483338/… –  Alexei Levenkov Nov 21 '12 at 1:29
Structs which expose mutating interfaces have very quirky semantics. It's far better to simply have structs expose their fields directly. –  supercat Nov 21 '12 at 18:12
add comment

Your best bet is probably to have your structures expose their fields directly, and then use code like:

  var temp = myList[3];
  temp.X += 4;
  myList[3] = temp;

I consider the failure of .net to provide any means of updating list items in place to be a significant weakness in .net, but would still consider an exposed-field struct as being far superior to any alternative in cases where one wishes to represent a small group of orthogonal values which should not be "attached" to any other such group (such as the coordinates in a point, the origin and size of a rectangle, etc.) The notion that structs should be "immutable" has been repeated as mantra for a long time, but that doesn't mean it's good advice. Such notion stems largely from two things:

  1. Structs which modify `this` in any members outside their constructors are quirky. Such quirks used to (and to some extent still do) apply to property setters, but not to structs which simply expose their fields directly. Because Microsoft wrapped all struct fields in properties, this meant that while mutable structures could have had sensible semantics if they'd had exposed fields, they ended up with quirky semantics; Microsoft then blamed the quirky semantics on the fact that structs were mutable, rather than on the needless wrapping of fields with properties.
  2. Some people like to model .net has only having one kind of object, as opposed to having value types and reference types as distinct kinds of entities. The behavior of so-called "immutable" value types is close enough to that of reference types that they can pretend they're the same thing, whereas the behavior of easily-mutable value types is vastly different. In reality, it's easier to understand the behavior of exposed-field value types than to understand all the corner cases where so-called "immutable" value types behave differently from reference types, and understanding the latter is impossible without understanding the former. Note that while value types may pretend to be immutable, there is in reality no such thing as an immutable value type. The only distinction is between those which can be mutated conveniently and those which can only be mutated awkwardly.

In reality, if a type is supposed to represent a small group of orthogonal values, an exposed-field struct is a perfect fit. Even if one has to use clunky code like that shown above to update a field of an item in a List<structType>, it's better than any alternative using class types or so-called "immutable" structs. Knowing that myList is a structure with an exposed field X would be enough to completely understand the code above. The only remotely decent alternative if one were using a class or "immutable" struct would be myList[3] = myList[3].WithX(myList[3].X + 4);, but that would require that the type in question to offer a WithX method (and presumably a WithWhatever() method for each field). Such methods would increase many fold the amount of code one would have to read to find out for certain what a method would actually do (one might expect that WithX would return a new instance which was identical to the old one except for the value of X, but one wouldn't know until one read all the code involved; by contrast, knowing that X is an exposed field of the structure type would be sufficient to know what the above code would do.

share|improve this answer
Supercat, thank you for being the first person to give me a practical answer rather than one that is based on mantra and tradition. I just want my code to be fast, and could care less about all the setter and getters which make things look pretty. Additionally, I have a hard time imagining that it wouldn't be faster to reference a parameter from a struct array (or List<T>) than it is from a list of objects by reference. Additionally, I see little distinction from a struct in C# than an object, as you have have methods inside structs, etc. –  reza Nov 21 '12 at 22:35
Why isn't there a simple STRUCT struct in C# that doesn't try to act like an object? Why not just not have structs if they are almost-functionally equivalent and add some other language to denote that you want a copy of the object or a reference to the object? –  reza Nov 21 '12 at 22:39
I do have to learn some of the jargon [convenient/awkward] [mutable/immutable] [reference/object/value] type. I'm assuming that immutable just means that you dont have a setter for a parameter outside the object. convenient/awkward I assume referes to how ugly the code looks to do something. It would be nice if references had a prefix like * to make them easy to spot (like C). all in all, I like c#, i think it takes a lot of the good aspects of java, C, perl -- though I don't like how it (at least it seems to me) forces you to write potentially slower code. –  reza Nov 21 '12 at 22:40
I also don't like how the limit on the comment size on this website but no limitation on the number of comments... –  reza Nov 21 '12 at 22:41
@reza: In .NET (and thus in C#), a struct definition actually defines two kinds of things: (1) the type of a heap object, which derives from System.ValueType which in turn inherits from Object, and which like all heap objects stores a type descriptor along with the contents of all public and private fields; (2) the type of a storage location which holds all the struct's public and private fields, but doesn't store any type information. Heap objects of structure types behave, from the perspective of outside code, like heap objects of class types. The biggest difference... –  supercat Nov 23 '12 at 22:23
show 2 more comments

Your Answer


