Is it possible to access the structure link from the <T> list to make changes?
From J.Richter "CLR via C #", 3rd edition:
Value types must be immutable: that is, they must not define any members that modify any field of type instances. In fact, I recommend that value types have their fields marked readonly, so that the compiler will throw errors if you accidentally write a method that tries to change the field.
...
Just keep in mind that value types and reference types have very different behavior depending on how they are 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 { get { return value; } } public void Change(int value) { this.value = value; } } and its use:
static void Main(string[] args) { MyStruct[] l = new MyStruct[] { new MyStruct(0) }; Console.WriteLine(l[0].Value); l[0].Change(10); Console.WriteLine(l[0].Value); Console.ReadLine(); } Conclusion:
0 10
So he does what you need.
However, the same will not work for List<T> . I think, for the reason mentioned by Alexei Levenkov. Therefore, I strongly recommend that you change the struct to class if the type in question is not immutable for each instance.
It is best for your structures to display their fields directly and then use the code, for example:
var temp = myList [3]; temp.X + = 4; myList [3] = temp;
I consider .net's refusal to provide any means of updating list items in place to be a significant weakness in .net, but will still consider the open field structure as far superior to any alternative when you want to represent a small group of orthogonal values, which should not be โattachedโ to any other such group (such as the coordinates at a point, the beginning and size of the rectangle, etc.). The notion that structures should be โunchangedโ has been repeated as a mantra for a long time, but this does not mean that this is good advice. This concept is mainly related to two things:
- Structures that modify `this` in any member outside their constructors are dodgy. The quirks that have been used (and to some extent so far) apply to property installers, but not to structures that simply expose their fields directly. Because Microsoft recruited all structure fields in properties, this meant that while mutable structures could have reasonable semantics, if they had fields, they would end up with bizarre semantics; Microsoft then blamed the bizarre semantics for the fact that the structures were volatile, not the unnecessary packing of property fields.
- Some people like to model .net, it has only one kind of object, unlike the presence of value types and reference types as separate types of objects. The behavior of the so-called "immutable" value types is close enough to the type of reference types that they can pretend that they are one and the same, while the behavior of easily variable value types is significantly different. Actually, itโs easier to understand the behavior of value types of open fields than to understand all angular cases when the so-called โimmutableโ value types behave differently than reference types, and understanding the latter is impossible without understanding the former. Note that while value types may claim to be immutable, there really is no such thing as a type of immutable value. The only difference is between those that can be mutated conveniently and those that can only be mutated awkwardly.
In fact, if a type should represent a small group of orthogonal values, an open-field structure is ideal. Even if you need to use obscene code to update an element field in a List<structType> , as shown above, it is better than any alternative that uses class types or so-called "immutable" structures. Knowing that myList is an open-field X structure, it would be enough to fully understand the code above. The only remote alternative if you use a class or an "immutable" structure would be myList[3] = myList[3].WithX(myList[3].X + 4); , but this requires that the type in question propose the WithX method (and presumably the WithWhatever() method for each field). Such methods would increase many times the amount of code that would need to be read in order to know exactly what the method would do (it could would expect WithX return a new instance that would be identical to the old, except for the value from X , but no one would know until it reads all the involved code, on the contrary, knowing that X is an open field of type structure, it would be enough to know what this code would do .