1

这是我想做的,我不知道是否有可能,或者我一直在以不正确的方式解决问题:

我有一个对象,其成员具有自定义属性,我正在使用该属性中的信息来搜索集合中的值,然后通过反射设置该给定属性的值。但是我的类型有一些更复杂的成员,成员不是简单的字符串或 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 的属性,当找到复杂值时,传递复杂的实际实例键入方法,以便它可以迭代其属性并在该实例中设置它们的值。

希望这可以进一步澄清这个问题。:)

提前致谢!

4

1 回答 1

2

正如它所写的那样,当您的方法运行时,您的 MyEntity 对象可能不会ComplexProperty填充,对吧?它只是空的。因此,您必须创建一个新实例MyOtherClassActivator.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);
    }

}
于 2012-08-21T23:01:31.760 回答