Установить частный сеттер для свойства через отражение

Я знаю, что у этого есть несколько канонических ответов (которые я успешно использовал в прошлом!) См. /questions/8108098/net-reflection-ustanovit-chastnuyu-sobstvennost/8108116#8108116 и /questions/44657341/mozhno-li-ustanovit-chastnuyu-sobstvennost-s-pomoschyu-otrazheniya/44657360#44657360. Для справки, эти методы включают использование SetValue метод на PropertyInfo свойства, или иным образом вызывая метод сеттера с отражением, или, в крайнем случае, непосредственно устанавливая фоновое поле. Тем не менее, ни один из этих методов сейчас не работает для меня, и мне любопытно, изменилось ли что-то, что нарушило эту функциональность.

Учтите следующее:

using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        var exampleInstance = new Example();
        var exampleType = typeof(Example);
        var fooProperty = exampleType.GetProperty("Foo"); // this works fine - the "GetSetMethod" method returns null, however

        // fails with the following:
        // [System.MethodAccessException: Attempt by method 'Program.Main()' to access method 'Example.set_Foo(Int32)' failed.]
        //fooProperty.SetValue(exampleInstance, 24);

        // same error here:
        //Run-time exception (line 14): Attempt by method 'Program.Main()' to access method 'Example.set_Foo(Int32)' failed.
        //exampleType.InvokeMember(fooProperty.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, exampleInstance, new object[] { 24 });
    }
}

public class Example 
{
    public int Foo { get; private set; }
}

Foo У собственности есть сеттер, это просто личное. Он также завершится неудачей, если я изменю установщик на защищенный, что кажется еще более странным, поскольку он больше не является установщиком только для инициализатора C#6. Это терпит неудачу как с.NET 4.5, так и.NET Core 2 в качестве среды выполнения. Что мне не хватает?

1 ответ

Решение

Такое поведение разработано. Есть некоторые строгие правила, которые регулируют способность злоупотреблять отражением таким образом.

Доступ к членам, которые обычно недоступны

На самом деле, если вы вообще планируете использовать рефлексию, в реальной жизни секнарио всю статью стоит прочитать. Вопросы безопасности для размышлений

У меня была аналогичная проблема (за исключением того, что я использую статическое свойство), и я смог вызвать частный сеттер следующим образом:

public static class Example 
{
    public static int Foo { get; private set; }
}

typeof(Example).GetProperty("Foo").SetMethod.Invoke(null, new object[] { 42});

Однако не тестировал нестатический.

Другие вопросы по тегам