If you have a property defined like this:
private DateTime modifiedOn;
public DateTime ModifiedOn
{
get { return modifiedOn; }
}
How do you set it to a certain value with Reflection?
I've tried both:
dto.GetType().GetProperty("ModifiedOn").SetValue(dto, modifiedOn, null);
and
dto.GetType().GetProperty("modifiedOn").SetValue(dto, modifiedOn, null);
but without any success. Sorry if this is a stupid question but it's the first time I'm using Reflection with C#.NET.
That has no setter; you'd need:
public DateTime ModifiedOn
{
get { return modifiedOn; }
private set {modifiedOn = value;}
}
(you might have to use BindingFlags
- I'll try in a moment)
Without a setter, you'd have to rely on patterns / field names (which is brittle), or parse the IL (very hard).
The following works fine:
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);
}
}
It also works with an auto-implemented property:
public DateTime ModifiedOn { get; private set; }
(where relying on the field-name would break horribly)
如果您的属性没有 setter,则不能对其调用 SetValue。
You could try to set the backing field and not the property; you should use GetField()
not GetProperty()
.
You need to set the field because you have no set property to set the property. Additional the BindingFlags.NonPublic is needed for not public objects.
dto.GetType().
GetField("modifiedOn",
BindingFlags.NonPublic|BindingFlags.SetField|BindingFlags.Instance).
SetValue(dto, valueToSet);
If you have a private property with a setter then you can use this Extension method to set a value:
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);
}
}
One way to do it, and this is might be the most correct way, considering that set
may or may not exist, is to use a specific accessor
var myc = new MyClass();
var pi = typeof(MyClass).GetProperty("Prop1", BindingFlags.NonPublic | BindingFlags.Instance);
if (pi.SetMethod != null) // check if you have 'set' accessor
pi.SetMethod.Invoke(myc, new object[]{ someValue });
else
{
// do nothing OR
throw new Exception("Attempted to set read-only property " + pi.Name);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.