使用反射访问遥远的父类中的私有字段将返回null

时间:2019-06-09 11:57:04

标签: c# reflection xamarin.forms

我正在尝试访问Xamarin.Forms.Element_id的私有字段。是Xamarin.Forms.Label的远亲。

void Handle_Clicked(object sender, System.EventArgs e)
{
    var label = new Label() { Text = "text" };
    var element = GetElement(label.GetType());
    var field = element.GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic);
    var runtimeFields = element.GetRuntimeFields();
    var runtimeField = runtimeFields.First(f => f.Name == "_id");

    Console.WriteLine("label: " + field.GetValue(label));
    Console.WriteLine("runtime label: " + runtimeField.GetValue(label));
}

我通过这种方法得到了Element基本类型

private Type GetElement(Type type)
{
    if (type.Name != "Element")
    {
        return GetElement(type.BaseType);
    }
    return type;
}

我成功获取_id字段和runtimeField-但调用GetValue(label)却得到null。设置断点并进行检查时,我可以看到label在BaseType中具有_id的值。但是该值不会写入控制台。为什么?


在xaml中创建标签时,我仍然无法从Xamarin.Forms.Element字段中获取空值。

_id

当设置断点时,我可以看到<Label Text="text" x:Name="label"/> 字段具有一个值。

1 个答案:

答案 0 :(得分:1)

我不确定为什么您甚至需要GetElement(Type)来获取元素的类型。 typeof(Element)可以正常工作。因此,要获取您的字段,您需要FieldInfo idField = typeof(Element).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic),并使用idField.GetValue(label)来获取其值。那肯定会给你对象的_id

根据问题代码的编写方式,

P.S,我想您正在处理某个标签的clicked事件。我不确定_id字段何时初始化,但是只有在将其添加到父级之后才可能初始化;并且您从刚刚创建的标签中获得了_id值,而不是使用sender参数。如果我认为正确,则可能要使用GetValue(sender)而不是GetValue(label)