首页 > 解决方案 > 有没有办法在 C# 表达式中创建对只读字段的引用?

问题描述

我正在尝试为一个方法创建一个 MethodCallExpression,该方法通过引用获取一个参数(并且可能会修改此参数)。此表达式是 ExpressionTree 的一部分,稍后会编译为委托。

对于非只读字段,一切都按预期工作,但是当我传入只读字段时,编译器会以某种方式按值传递字段,并且更改参数不会影响只读字段。只读字段来自的对象可以是结构或对象。

如何欺骗编译器将只读字段作为实际参考传递?

我知道,它应该是只读的,但是通过反射,您也可以修改该字段。(即使有结构FieldInfo.SetValueDirect(__makeref(...), value):)

示例代码:

internal class Program
{
    private struct Foo
    {
        private readonly int MyInt;

        public Foo(int myInt)
        {
            MyInt = myInt;
        }
    }

    public static void IncrementInt(ref int i)
    {
        i++;
    }

    private delegate void RefAction<T>(ref T parameter);

    private static void Main(string[] args)
    {
        var field = typeof(Foo).GetField("MyInt", BindingFlags.NonPublic | BindingFlags.Instance);
        var method = typeof(Program).GetMethod(nameof(IncrementInt));

        var parameter = Expression.Parameter(typeof(Foo).MakeByRefType());
        var call = Expression.Call(method, Expression.MakeMemberAccess(parameter, field));
        var deleg = Expression.Lambda<RefAction<Foo>>(call, parameter).Compile();

        var foo = new Foo(0);
        deleg(ref foo);
    }
}

标签: c#pass-by-referenceexpression-treesreadonly

解决方案


推荐阅读