如何设置也是类的成员的属性?

时间:2012-08-21 22:57:05

标签: c# reflection

这就是我想做的事情,我不知道是否有可能或者我是以不正确的方式攻击问题:

我有一个对象,其成员具有自定义属性,我使用该属性中的信息来搜索集合中的值,然后使用反射设置该给定属性的值。但是我的类型有一些更复杂的成员,成员不是简单的字符串或int,但是也是具有属性的类来设置它们的值。

所以,要使用反射设置值,我需要我正在改变的对象的实例,所以我的问题是:

如何获取实际成员,以便我可以使用他们拥有的属性检查并获取其值?

这里有一些我拥有的和我想要的示例代码:

public class MyEntity
{
    [CustomAttribute("Info to Set Values")]
    public string SimpleProperty {get;set;}

    public MyOtherClass ComplexProperty {get;set;}

    public static bool SetSimpleValueTypes(object instance, IEnumerable<Value> values){
        var mappedProperties = instance.GetType()
                                   .GetProperties()
                                   .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length > 0);

        foreach (PropertyInfo property in mappedProperties)
        {
           /*...and then some code to get the Value to set in the property*/
           var value = GetValue(values);
           property.SetValue(instance, value, null);
        }
    }

}

public class MyOtherClass
{
    [CustomAttribute("Info to Set Values")]
    public string SimpleInnerProperty {get;set;}
}

在上面的代码中,在方法SetSimpleValueTypes中,我获得了具有CustomAttribute属性的给定实例的所有属性,然后我迭代这些PropertyInfo并使用我传递给它的实例设置值;我会用它如下:

MyEntity entity = new MyEntity();
MyEntity.SetSimpleValueTypes(entity, valuesFromSomeWhere);

这将正确设置所有简单类型属性的值:string,int等;但是现在,我还需要在ComplexProperty中设置值,所以使用一种不那么灵活的方法,我可以这样做:

MyEntity entity = new MyEntity();
MyEntity.SetSimpleValueTypes(entity, valuesFromSomeWhere);
MyEntity.SetSimpleValueTypes(entity.ComplexProperty, valuesFromSomeWhere);

所以,我真的想做的是,而不是显式调用ComplexProperty将它传递给SetSimpleValueTypes方法,我想迭代抛出MyEntity的属性,当找到复杂值时,传递实际的实例方法的复杂类型,因此它可以迭代其属性并在该实例中设置它们的值。

希望这可以更多地澄清这个问题。 :)

提前致谢!

1 个答案:

答案 0 :(得分:2)

在编写时,你的MyEntity对象可能在你的方法运行时没有填充ComplexProperty,对吧?它只会为空。因此,您必须创建MyOtherClass的新实例(例如,使用Activator.CreateInstance(),或者可能是DI框架),然后在该对象上递归调用您的方法。

public static bool SetValueTypes(object instance, IEnumerable<Value> values){
    var mappedProperties = instance.GetType()
                               .GetProperties()
                               .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length > 0);

    foreach (PropertyInfo property in mappedProperties)
    {
       /*...and then some code to get the Value to set in the property*/
       var value = GetValue(values);
       property.SetValue(instance, value, null);
    }

    var complexProperties = instance.GetType()
                               .GetProperties()
    // Either assume that unmapped properties are all complex,
    // or use your own criteria. Maybe anything whose type is
    // a class and not a string?
                               .Where(type => type.GetCustomAttributes(typeof(CustomAttribute), true).Length == 0);
    foreach (PropertyInfo property in mappedProperties)
    {
       var value = Activator.CreateInstance(property.PropertyType);
       SetValueTypes(value, values);
       property.SetValue(instance, value, null);
    }

}