How to mutate a boxed struct using IL

后端 未结 5 1066
执笔经年
执笔经年 2020-12-24 07:41

Imagine we have a mutable struct (yes, don\'t start):

public struct MutableStruct
{
    public int Foo { get; set; }
    public override string          


        
5条回答
  •  不知归路
    2020-12-24 08:38

    Even without unsafe code, pure C#:

    using System;
    
    internal interface I {
      void Increment();
    }
    
    struct S : I {
      public readonly int Value;
      public S(int value) { Value = value; }
    
      public void Increment() {
        this = new S(Value + 1); // pure evil :O
      }
    
      public override string ToString() {
        return Value.ToString();
      }
    }
    
    class Program {
      static void Main() {
        object s = new S(123);
        ((I) s).Increment();
        Console.WriteLine(s); // prints 124
      }
    }
    

    In C#, this reference inside value types instance methods actually is ref-parameter (or out-parameter in value type constructor, and that is why this can't be captured into closures, just like ref/out parameters in any methods) and can be modified.

    When struct instance method is invoked on unboxed value, this assignment will effectively replace value at the call site. When instance method is invoked on boxed instance (via virtual call or interface call like in the example above), ref-parameter is pointed to the value inside the box object, so it is possible to modify boxed value.

提交回复
热议问题