Установить значение свойства с частным доступом

1

У меня этот класс:

public class Foo
{
    public string Name { get; private set; }
}

Если я напишу это:

Foo foo = new Foo();
foo.Name = "Nocigar";

Очевидно, я получаю ошибку компилятора. Но если я напишу это:

static void Main()
{
    Foo foo = new Foo();

    Action<Foo, string> act = Build();
    act(foo, "Woot");

    Debug.WriteLine(foo.Name);
}

static Action<Foo, string> Build()
{
    ParameterExpression fooParam =
        Expression.Parameter(typeof(Foo),
        "foo");

    ParameterExpression nameParam =
        Expression.Parameter(typeof(string),
        "name");

    MemberExpression propertyValue =
        Expression.Property(fooParam,
        "Name");

    BinaryExpression assignExpression =
        Expression.Assign(propertyValue,
        nameParam);

    LambdaExpression lambda =
        Expression.Lambda(typeof(Action<Foo, string>),
        assignExpression,
        fooParam,
        nameParam);

    return (Action<Foo, string>)lambda.Compile();
}

Он компилируется и запускается без проблем, записывая "Woot" в окно отладки. Что дает?

Я намереваюсь использовать эту функцию в некотором коде для отображения из устройства чтения данных в POCO. Я обеспокоен тем, что это может быть побочным эффектом, а не предполагаемым поведением, и задаться вопросом, может ли кто-нибудь пролить свет на причины этого.

  • 4
    С выражениями вы генерируете код, как вы можете сделать с Reflection.Emit но доступ к элементу ограничен только компилятором во время компиляции (это выполняется только во время выполнения только для сигнатуры метода), тогда с помощью выражений вы обойдете эту проверку (как вы можете сделать, используя сырое отражение).
Теги:

1 ответ

2
Лучший ответ

Это не побочный эффект. С отражением или выражениями вы можете получить доступ к таким частным членам, как это, например:

var dateTimeType = typeof (DateTime);
MethodInfo[] privateMthods = dateTimeType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
privateMthods.ToList().ForEach(a=> Console.WriteLine(a.Name.ToString()));

Как написано в книге "Метапрограммирование в.NET" Кевина Хаззарда и Джейсона Бока

"Theres также значение NonPublic, что означает, что вы можете видеть частный и защищенный контент через Reflection API. В зависимости от вашего представления это может показаться серьезным нарушением безопасности, если учесть, что это позволяет произвольному коду изменять значения частных полей в объекте, но только привилегированный код может использовать вызовы отражения. Если у вас нет такого уровня доступа, ваше использование рефлекса не удастся ". -page 46

Вы можете также рассмотреть это (опять же из вышеупомянутой книги):

"Как вы, вероятно, уже догадались с приложением Windows 8 и его моделью безопасности, вы можете получать доступ только к открытым членам, вы не можете получить доступ к закрытым членам. Опять же, эти изменения строго предназначены для приложений Windows 8. Если вы планируете использовать.NET 4.5 вне Windows 8, вы можете использовать полный класс Type. " - стр. 318

Эта статья также полезна: соображения безопасности для отражения

Ещё вопросы

Сообщество Overcoder
Наверх
Меню