Доступ к закрытому полю в дальнем родительском классе с отражением возвращает ноль - PullRequest
0 голосов
/ 09 июня 2019

Я пытаюсь получить доступ к закрытому полю _id в Xamarin.Forms.Element. Который является дальним родителем 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));
}

Я получаю базовый тип элемента с помощью этого метода

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

Я успешно получаю _id field и runtimeField - но при вызове GetValue(label) я получаю ноль. При установке точки останова и проверке я вижу, что label имеет значение для _id в Xamarin.Forms.Element BaseType. Но это значение не записывается в консоль. Почему?


При создании метки в xaml я все равно получаю ноль из поля _id.

<Label Text="text" x:Name="label"/>

И при установке точки останова я вижу, что поле _id имеет значение.

1 Ответ

1 голос
/ 09 июня 2019

Я не уверен, зачем вам вообще нужно GetElement(Type), чтобы получить тип элемента.typeof(Element) будет работать просто отлично.Итак, чтобы получить свое поле, вам нужно FieldInfo idField = typeof(Element).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic), а чтобы получить его значение, используйте idField.GetValue(label).Это определенно дало бы вам _id.

PS от способа написания кода в вопросе, я предположил, что вы обрабатываете событие clicked какой-то метки.Я не уверен, когда _id поле инициализируется, но это возможно только после его добавления к родителю;и вы получаете значение _id из только что созданной метки вместо использования параметра sender.Если я предположил, что вы правы, вы можете использовать GetValue(sender) вместо GetValue(label).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...