开发者

Get reference to variable from FieldInfo

开发者 https://www.devze.com 2023-01-20 15:27 出处:网络
I am working on a project where a field name from XML is loaded and the field with that name is returned 开发者_JAVA百科and added to the current object. The problem is that FieldInfo.GetValue seems to

I am working on a project where a field name from XML is loaded and the field with that name is returned 开发者_JAVA百科and added to the current object. The problem is that FieldInfo.GetValue seems to return the current value of the field, not a reference. Is there any way to get around this?


No unfortunately there is not. The design of FieldInfo.GetValue is to provide the value and not a reference. There is no other suitable method on FieldInfo to provide a reference either.

One reason why is that doing so would be simply unsafe. Imagen the scenario where the object is a struct on the stack. If a FieldInfo could provide a reference to a field of that struct then it would be supplying a reference to a piece of the stack which could go away at any moment. Reading or writing that reference after the stack went away would be incorrect and a type safety violation.


You can get it with an expression tree. This works for NativeAOT too!

private delegate ref int GetRefDelegate(MyClass obj);

private static ref int EchoRef(ref int x)
{
    return ref x;
}

private class
{
    public in MyField;
}

public static Main()
{
    var objParam = Expression.Parameter(typeof(Test), "obj");
    var echoRef = Expression.Lambda<GetRefDelegate>(
        Expression.Call(
            typeof(Program).GetMethod(nameof(EchoRef), BindingFlags.Static | BindingFlags.NonPublic),
            new Expression[]
            {
                Expression.Field(objParam, typeof(Test).GetField("MyField"))
            }
        ),
        false,
        new ParameterExpression[] { objParam }
    );

    var obj = new MyClass();
    ref int gotRef = ref echoRef.Compile()(obj);
}

For some reason, the expression tree compiler can understands that a field reference is needed with a method invocation with a reference parameter, but it cannot recognize the same when the return type is with a reference parameter. That's why you need to invoke the dummy EchoRef method.

0

精彩评论

暂无评论...
验证码 换一张
取 消