.NET Reflection设置私有属性

时间:2009-11-22 10:51:05

标签: c# .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 with C#.NET。

6 个答案:

答案 0 :(得分:35)

没有setter;你需要:

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

(您可能需要使用BindingFlags - 我会稍后尝试一下)

如果没有setter,你必须依赖模式/字段名称(这很脆弱),或者解析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; }

(依赖字段名称可能会破坏)

答案 1 :(得分:3)

您可以尝试设置支持字段而不是属性;您应该使用GetField()而不是GetProperty()

答案 2 :(得分:2)

如果您的财产没有设置者,则无法在其上调用SetValue。

答案 3 :(得分:1)

您需要设置该字段,因为您没有设置属性的set属性。 另外,对于非公共对象,还需要BindingFlags.NonPublic。

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

答案 4 :(得分:0)

如果您拥有带有setter的私有属性,则可以使用此Extension方法设置值:

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);
    }
}

答案 5 :(得分:0)

一种方法,这可能是最正确的方法,考虑到 df=pd.DataFrame({"years":["Y0","Y1","Y2","Y3"], "price1":[0.01, 0.0029,0.00368,0.00439536], "price2":[0.02, 0.001, float("9.161781253394068e-04"),0.001718]}) df.iloc[1:,1:] = df.iloc[1:,1:].mul(0.75) 可能存在也可能不存在,是使用特定的访问器

set