Подтвердить что ты не робот

.NET Reflection задает частную собственность

Если у вас есть свойство, определенное следующим образом:

private DateTime modifiedOn;
public DateTime ModifiedOn
{
    get { return modifiedOn; }
}

Как вы устанавливаете его в определенное значение с помощью Reflection?

Я пробовал оба:

dto.GetType().GetProperty("ModifiedOn").SetValue(dto, modifiedOn, null);

и

dto.GetType().GetProperty("ModifiedOn").SetValue(dto, modifiedOn, null);

но без каких-либо успехов. Извините, если это глупый вопрос, но это первый раз, когда я использую Reflection с С#.NET.

4b9b3361

Ответ 1

В нет нет сеттера; вам понадобится:

public DateTime ModifiedOn
{
    get { return modifiedOn; }
    private set {modifiedOn = value;}
}

(вам, возможно, придется использовать BindingFlags - я попробую в одно мгновение)

Без сеттера вам придется полагаться на имена паттернов/полей (которые хрупки) или анализировать IL (очень сложно).

Следующее прекрасно работает:

using System;
class Test {
    private DateTime modifiedOn;
    public DateTime ModifiedOn {     
        get { return modifiedOn; }
        private set { modifiedOn = value; }
    }
}
static class Program {
    static void Main() {
        Test p = new Test();
        typeof(Test).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

Он также работает с автоматически реализованным свойством:

public DateTime ModifiedOn { get; private set; }

(где полагаться на имя поля будет ужасно нарушено)

Ответ 2

Вы можете попытаться установить поле поддержки, а не свойство; вы должны использовать GetField() not GetProperty().

Ответ 3

Если ваше свойство не имеет сеттера, вы не можете вызвать SetValue на нем.

Ответ 4

Вам нужно установить поле, потому что у вас нет свойства set для установки свойства. Дополнительный BindingFlags.NonPublic необходим для не общедоступных объектов.

dto.GetType().
    GetField("modifiedOn", 
    BindingFlags.NonPublic|BindingFlags.SetField|BindingFlags.Instance).
    SetValue(dto, valueToSet);

Ответ 5

Если у вас есть частная собственность с установщиком, вы можете использовать этот метод расширения для установки значения:

using System.Reflection;

public static class ObjectExtensions
{
    public static void SetPrivateValue<T>(this T obj, string propertyName, object value)
    {
        var type = typeof(T);
        type.GetTypeInfo().GetDeclaredProperty(propertyName).SetValue(obj, value, null);
    }
}