.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.
Ответы
Ответ 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);
}
}