What are good uses for mutable structures?

So, I know that volatile structures / value types are considered "evil" in .Net. So why can they be made? What are some useful applications for mutable structures that justify adding this function to the CLR in the first place?

+6
source share
3 answers

Great question! Personally, I'm definitely not a fan, however, some people working on things like CF / XNA will swear that they need an extra bit of performance that they can use with structures, which usually involves changing them. This argument has some meaning if the structure is accessed directly into the array, in a public field or accessed via ref , but in many cases you can be bitten by chomping through the stack space, duplicating the structure in size many times on the stack.

If you use structs, mutable-or-not, and if you use serialization, then the real problem may be an unstable structure completely . Partial or "unique" immutability may be the answer here, but the same framework that is tempted for value types also has more reflection restrictions, making complex serialization based on private / field. So changeable is convenient.

All of the above are really examples of using a structure to store what is actually better classified as an object. Net values ​​do not change. Ever. So complete immutability is beautiful.

As a last thought ... not an excuse for existence, but she does an excellent interview for fodder, and is great for sorting out recklessness. Perhaps it was developed by people acting as consultants, p

+3
source

Partially mutable structures are good for creating builders for these structures.

So, if you have something like:

 namespace StructEx { public struct AStruct { public int AnInt { get; internal set; } } public class AStructBuilder { public AStruct BuildStruct(int anInt) { return new AStruct { AnInt = anInt }; } } } 

In one assembly, and then anything outside this assembly cannot change the structure you create, but creating them is easy.

+2
source

Mutable structs are the only data type in .net that can implement mutable semantics of values. Some people, such as Eric Lippert, hate them because they make life harder for compiler authors, but the semantics they offer are often much clearer than those available with reference types.

For example, suppose one has a class and structure type, as well as an interface as follows:

  struct myStruct {public int v;  ... other stuff ...};
 class myClass {public int v;  ... other stuff ...};
 interface ISample {
   void useStructByValue (myStruct z);
   void useStructByReference (ref myStruct z);
   void useClassByValue (myClass z);
   void useClassByReference (ref myClass z);
 }

and consider the following method:

  void test (myStruct struct1, myStruct struct2, myClass class1, myClass class2,
   ISample munger)
 {
   for (int i = 0; i <5; i ++)
   {
     munger.useStructByValue (struct1);  // S1
     munger.useStructByReference (ref struct2);  // S2
     munger.useClassByvalue (class1);  // S3
     munger.useClassByReference (ref class2);  // S4
   }
 }

Assuming munger is not using any insecure code, which of the elements passed may have a .v field affected by which of the four statements? I would suggest that without even seeing the whole definition of struct1 or any part of the munger implementation, we can say that struct1.v will not be modified by any of them. Guaranteed. In addition, struct2.v can be changed to S2, but not by any other statement. Again, guaranteed. However, the values ​​of class1.v and class2.v can be changed by any of the operators; the only way to find out which operator class1.v or class2.v can change is to study the code for each individual type that will ever, or in the future, implement ISample.

In other words, structures contain semantics that are limited but clearly defined. Classes do not work.

By the way, due to limitations in the operation of properties, you cannot directly modify or pass by reference the property fields of the structure. However, code like:

  List <myStruct> myList;
 ...
 myStruct tempStruct = myList [1];
 tempStrict.v = 5;
 myList [1] = tempStruct;

it is not thread safe yet, it has clear and obvious semantics. Replace myClass for myStruct, and confidence exits the window. If each list item has an unshared instance of myClass, you can simply say myList[1].v = 5; Nice and comfortable. Unfortunately, determining whether a list item is a unique instance of myClass is almost impossible. If someone, trying to copy the values ​​in myList[1] to myList[0] , said something like myList[0] = myList[1]; , such an operator would work, but as a result, a subsequent entry in myList[1].v also affect myList[0].v . Shockingly nasty. Structures would not have this problem.

+2
source

Source: https://habr.com/ru/post/886413/


All Articles