<p>I have a list of structs and I want to change one element. For example :</p>

<pre><code>MyList.Add(new MyStruct("john");
MyList.Add(new MyStruct("peter");
</code></pre>

<p>Now I want to change one element:</p>

<pre><code>MyList[1].Name = "bob"
</code></pre>

<p>However, whenever I try and do this I get the following error:</p>

<blockquote>
  <p>Cannot modify the return value of
  System.Collections.Generic.List.this[int]‘ because it is not
  a variable</p>
</blockquote>

<p>If I use a list of classes, the problem doesn't occur.</p>

<p>I guess the answer has to do with structs being a value type.</p>

<p>So, if I have a list of structs should I treat them as <em>read-only</em>? If I need to change elements in a list then I should use classes and not structs?</p>

[{'answer_id': 51537, 'author': 'Andrew', 'author_id': 1948, 'author_profile': 'https://Stackoverflow.com/users/1948', 'pm_score': 6, 'selected': True, 'text': '<pre><code>MyList[1] = new MyStruct("bob");\n</code></pre>\n\n<p>structs in C# should almost always be designed to be immutable (that is, have no way to change their internal state once they have been created).</p>\n\n<p>In your case, what you want to do is to replace the entire struct in specified array index, not to try to change just a single property or field.</p>\n'}, {'answer_id': 51585, 'author': 'Gishu', 'author_id': 1695, 'author_profile': 'https://Stackoverflow.com/users/1695', 'pm_score': 6, 'selected': False, 'text': '<p>Not quite. Designing a type as class or struct shouldn\'t be driven by your need to store it in collections :) You should look at the \'semantics\' needed</p>\n\n<p>The problem you\'re seeing is due to value type semantics. Each value type variable/reference is a new instance. When you say\n</p>\n\n<pre><code>Struct obItem = MyList[1];\n</code></pre>\n\n<p>what happens is that a new instance of the struct is created and all members are copied one by one. So that you have a clone of MyList[1] i.e. 2 instances.\nNow if you modify obItem, it doesn\'t affect the original.</p>\n\n<pre><code>obItem.Name = "Gishu";  // MyList[1].Name still remains "peter"\n</code></pre>\n\n<p>Now bear with me for 2 mins here (This takes a while to gulp down.. it did for me :)\nIf you really need structs to be stored in a collection and modified like you indicated in your question, you\'ll have to make your struct expose an interface (<em>However this will result in boxing</em>). You can then modify the actual struct via an interface reference, which refers to the boxed object. </p>\n\n<p>The following code snippet illustrates what I just said above</p>\n\n<pre><code>public interface IMyStructModifier\n{\n    String Name { set; }\n}\npublic struct MyStruct : IMyStructModifier ...\n\nList&lt;Object&gt; obList = new List&lt;object&gt;();\nobList.Add(new MyStruct("ABC"));\nobList.Add(new MyStruct("DEF"));\n\nMyStruct temp = (MyStruct)obList[1];\ntemp.Name = "Gishu";\nforeach (MyStruct s in obList) // =&gt; "ABC", "DEF"\n{\n    Console.WriteLine(s.Name);\n}\n\nIMyStructModifier temp2 = obList[1] as IMyStructModifier;\ntemp2.Name = "Now Gishu";\nforeach (MyStruct s in obList) // =&gt; "ABC", "Now Gishu"\n{\n    Console.WriteLine(s.Name);\n}\n</code></pre>\n\n<p>HTH. Good Question.<br>\n<strong>Update:</strong> @Hath - you had me running to check if I overlooked something that simple. (It would be inconsistent if setter properties dont and methods did - the .Net universe is still balanced :)<br>\n<em>Setter method doesn\'t work</em><br>\nobList2[1] returns a copy whose state would be modified. Original struct in list stays unmodified. So Set-via-Interface seems to be only way to do it.</p>\n\n<pre><code>List&lt;MyStruct&gt; obList2 = new List&lt;MyStruct&gt;();\nobList2.Add(new MyStruct("ABC"));\nobList2.Add(new MyStruct("DEF"));\nobList2[1].SetName("WTH");\nforeach (MyStruct s in obList2) // =&gt; "ABC", "DEF"\n{\n    Console.WriteLine(s.Name);\n}\n</code></pre>\n'}, {'answer_id': 53038, 'author': 'Jason Olson', 'author_id': 5418, 'author_profile': 'https://Stackoverflow.com/users/5418', 'pm_score': 4, 'selected': False, 'text': '<p>It\'s not so much that structs are "immutable." </p>\n\n<p>The real underlying issue is that structs are a Value type, not a Reference type. So when you pull out a "reference" to the struct from the list, it is creating a new copy of the entire struct. So any changes you make on it are changing the copy, not the original version in the list. </p>\n\n<p>Like Andrew states, you have to replace the entire struct. As that point though I think you have to ask yourself why you are using a struct in the first place (instead of a class). Make sure you aren\'t doing it around premature optimization concerns.</p>\n'}, {'answer_id': 8558544, 'author': 'supercat', 'author_id': 363751, 'author_profile': 'https://Stackoverflow.com/users/363751', 'pm_score': 3, 'selected': False, 'text': '<p>There is nothing wrong with structs that have exposed fields, or that allow mutation via property setters.  Structs which mutate themselves in response to methods or property getters, however, are dangerous because the system will allow methods or property getters to be called on temporary struct instances; if the methods or getters make changes to the struct, those changes will end up getting discarded.</p>\n\n<p>Unfortunately, as you note, the collections built into .net are really feeble at exposing value-type objects contained therein.  Your best bet is usually to do something like:</p>\n\n<pre>\n  MyStruct temp = myList[1];\n  temp.Name = "Albert";\n  myList[1] = temp;\n</pre>\n\n<p>Somewhat annoying, and not at all threadsafe.  Still an improvement over a List of a class type, where doing the same thing might require:</p>\n\n<pre>\n  myList[1].Name = "Albert";\n</pre>\n\n<p>but it might also require:</p>\n\n<pre>\n  myList[1] = myList[1].Withname("Albert");\n</pre>\n\n<p>or maybe</p>\n\n<pre>\n  myClass temp = (myClass)myList[1].Clone();\n  temp.Name = "Albert";\n  myList[1] = temp;\n</pre>\n\n<p>or maybe some other variation.  One really wouldn\'t be able to know unless one examined myClass as well as the other code that put things in the list.  It\'s entirely possible that one might not be able to know whether the first form is safe without examining code in assemblies to which one does not have access.  By contrast, if Name is an exposed field of MyStruct, the method I gave for updating it will work, regardless of what else MyStruct contains, or regardless of what other things may have done with myList before the code executes or what they may expect to do with it after.</p>\n'}, {'answer_id': 56895908, 'author': 'David Klempfner', 'author_id': 2063755, 'author_profile': 'https://Stackoverflow.com/users/2063755', 'pm_score': 2, 'selected': False, 'text': '<p>In addition to the other answers, I thought it could be helpful to explain why the compiler complains.</p>\n\n<p>When you call <code>MyList[1].Name</code>, unlike an array, the <code>MyList[1]</code> actually calls the indexer method behind the scenes. </p>\n\n<p>Any time a method returns an instance of a struct, you\'re getting a copy of that struct (unless you use ref/out).</p>\n\n<p>So you\'re getting a copy and setting the <code>Name</code> property on a copy, which is about to be discarded since the copy wasn\'t stored in a variable anywhere.</p>\n\n<p><a href="http://reinventingthewheel.azurewebsites.net/ModifyStruct.aspx" rel="nofollow noreferrer">This</a> tutorial describes what\'s going on in more detail (including the generated CIL code).</p>\n'}, {'answer_id': 68538262, 'author': 'Bob Bryan', 'author_id': 643828, 'author_profile': 'https://Stackoverflow.com/users/643828', 'pm_score': 0, 'selected': False, 'text': "<p>As of C#9, I am not aware of any way to pull a struct by reference out of a generic container, including <code>List&lt;T&gt;</code>. As Jason Olson's answer said:</p>\n<p><em>The real underlying issue is that structs are a Value type, not a Reference type. So when you pull out a &quot;reference&quot; to the struct from the list, it is creating a new copy of the entire struct. So any changes you make on it are changing the copy, not the original version in the list.</em></p>\n<p>So, this can be pretty inefficient. SuperCat's answer, even though it is correct, compounds that inefficiency by copying the updated struct back into the list.</p>\n<p>If you are interested in maximizing the performance of structs, then use an array instead of <code>List&lt;T&gt;</code>. The indexer in an array returns a reference to the struct and does not copy the entire struct out like the <code>List&lt;T&gt;</code> indexer. Also, an array is more efficient than <code>List&lt;T&gt;</code>.</p>\n<p>If you need to grow the array over time, then create a generic class that works like <code>List&lt;T&gt;</code>, but uses arrays underneath.</p>\n<p>There is an alternative solution. Create a class that incorporates the structure and create public methods to call the methods of that structure for the required functionality. Use a <code>List&lt;T&gt;</code> and specify the class for T.  The structure may also be returned via a ref returns method or ref property that returns a reference to the structure.</p>\n<p>The advantage of this approach is that it can be used with any generic data structure, like <code>Dictionary&lt;TKey, TValue&gt;</code>. When pulling a struct out of a <code>Dictionary&lt;TKey, TValue&gt;</code>, it also copies the struct to a new instance, just like <code>List&lt;T&gt;</code>. I suspect that this is true for all C# generic containers.</p>\n<p>Code example:</p>\n<pre><code>public struct Mutable\n{\n   private int _x;\n\n   public Mutable(int x)\n   {\n      _x = x;\n   }\n\n   public int X =&gt; _x; // Property\n\n   public void IncrementX() { _x++; }\n}\n\npublic class MutClass\n{\n   public Mutable Mut;\n   //\n   public MutClass()\n   {\n      Mut = new Mutable(2);\n   }\n\n   public MutClass(int x)\n   {\n      Mut = new Mutable(x);\n   }\n\n   public ref Mutable MutRef =&gt; ref Mut; // Property\n\n   public ref Mutable GetMutStruct()\n   {\n      return ref Mut;\n   }\n}\n\nprivate static void TestClassList()\n{\n   // This test method shows that a list of a class that holds a struct\n   // may be used to efficiently obtain the struct by reference.\n   //\n   var mcList = new List&lt;MutClass&gt;();\n   var mClass = new MutClass(1);\n   mcList.Add(mClass);\n   ref Mutable mutRef = ref mcList[0].MutRef;\n   // Increment the x value defined in the struct.\n   mutRef.IncrementX();\n   // Now verify that the X values match.\n   if (mutRef.X != mClass.Mut.X)\n      Console.Error.WriteLine(&quot;TestClassList: Error - the X values do not match.&quot;);\n   else\n      Console.Error.WriteLine(&quot;TestClassList: Success - the X values match!&quot;);\n}\n</code></pre>\n<p>Output on console window:</p>\n<pre><code>TestClassList: Success - the X values match!\n</code></pre>\n<p>For the following line:</p>\n<pre><code>ref Mutable mutRef = ref mcList[0].MutRef;\n</code></pre>\n<p>I initially and inadvertently left out the ref after the equal sign. The compiler didn't complain, but it did produce a copy of the struct and the test failed when it ran. After adding the ref, it ran correctly.</p>\n"}, {'answer_id': 72507955, 'author': 'DaemonFire', 'author_id': 11522147, 'author_profile': 'https://Stackoverflow.com/users/11522147', 'pm_score': 2, 'selected': False, 'text': '<p>In .Net 5.0, you can use <a href="https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.collectionsmarshal.asspan?view=net-5.0" rel="nofollow noreferrer"><code>CollectionsMarshal.AsSpan()</code></a> (<a href="https://source.dot.net/#System.Private.CoreLib/CollectionsMarshal.cs,b48f5c98e43560f8" rel="nofollow noreferrer">source</a>, <a href="https://github.com/dotnet/runtime/issues/27061" rel="nofollow noreferrer">GitHub issue</a>) to get the underlying array of a <code>List&lt;T&gt;</code> as a <code>Span&lt;T&gt;</code>.</p>\n<pre><code>var listOfStructs = new List&lt;MyStruct&gt; { new MyStruct() };\nSpan&lt;MyStruct&gt; spanOfStructs = CollectionsMarshal.AsSpan(listOfStructs);\nspanOfStructs[0].Value = 42;\nAssert.Equal(42, spanOfStructs[0].Value);\n\nstruct MyStruct { public int Value { get; set; } }\n</code></pre>\n<p>This works because the <code>Span&lt;T&gt;</code> indexer uses a C# 7.0 feature called ref returns. The indexer is declared with a <code>ref T</code> return type, which provides semantics like that of indexing into arrays, returning a reference to the actual storage location.</p>\n<p>In comparison the <code>List&lt;T&gt;</code> indexer is not ref returning instead returning a copy of what lives at that location.</p>\n<p>Keep in mind that this is still unsafe: if the <code>List&lt;T&gt;</code> reallocates the array, the <code>Span&lt;T&gt;</code> previously returned by <code>CollectionsMarshal.AsSpan</code> won\'t reflect any further changes to the <code>List&lt;T&gt;</code>. (Which is why the method is hidden in the <code>System.Runtime.InteropServices.CollectionsMarshal</code> class.)</p>\n<p><a href="https://stackoverflow.com/a/60514418/11522147">Source</a></p>\n'}]
['https://Stackoverflow.com/questions/51526', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3989/']