这就是我想做的事情,我不知道是否有可能或者我是以不正确的方式攻击问题:
我有一个对象,其成员具有自定义属性,我使用该属性中的信息来搜索集合中的值,然后使用反射设置该给定属性的值。但是我的类型有一些更复杂的成员,成员不是简单的字符串或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的属性,当找到复杂值时,传递实际的实例方法的复杂类型,因此它可以迭代其属性并在该实例中设置它们的值。
希望这可以更多地澄清这个问题。 :)
提前致谢!
答案 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);
}
}