string strRequestValue = null; PropertyInfo[] proInfo = Modules.GetType().GetProperties(); foreach (PropertyInfo p in proInfo) { if (p.PropertyType.IsClass) { PropertyInfo[] childProInfo = p.PropertyType.GetProperties(); foreach (PropertyInfo item in childProInfo) { strRequestValue = Request[p.Name + "." + item.Name]; if (strRequestValue != null) { item.SetValue(p, GetValue(strRequestValue, item), null); } } } ………… }
上面代码中Modules表示当前要赋值的实体类对象,比如这样一个实体类
public class EntityArticle { private EntityNode _node; public EntityNode node { get { return _node; } set { _node = value; } } private EntityNodeAttach _nodeAttach; public EntityNodeAttach nodeAttach { get{return _nodeAttach;} set{_nodeAttach = value;} } …… }
问题就出在:item.SetValue(p, GetValue(strRequestValue, item), null);
SetValue的第一个参数需要“设置其属性值得对象”,但是我不知道在这里如何得到这个属性对象
希望能有人指点一下,谢谢!
用 Activator.CreateInstance.
谢谢了,就是这个了。
谢谢你的解答,我还想请教一下,在取值的时候我应该怎么获取当前PropertyInfo所代表的对象呢?
PropertyInfo proInfo = action.Modules.GetType().GetProperty(nameArray[0]); if (proInfo.PropertyType.IsClass && proInfo != null) { PropertyInfo pt = proInfo.PropertyType.GetProperty(nameArray[1]); if (pt != null) return pt.GetValue(proInfo, null); }
nameArray[0]:表示EntityArticle的属性名称(如:node);nameArray[1]:表示EntityArticle的类属性的属性名称(如:EntityNode中有一个title的属性)
和上面的问题一样return pt.GetValue(proInfo, null);肯定也会报“对象与目标类型不匹配”的异常,请问这里可以怎么处理呢?试了好久都没有找到解决的办法,希望能帮忙解答一下。
@psforever: PropertyInfo.GetValue 的第一个参数是将返回其值的对象,也就是说 pt.GetValue(proInfo.null) 是不对的,而是 :
EntityNode node = new EntityNode();
pt.GetValue(node,null); // 这里的 pt 是 EntityNode 的 Title 属性。
@Launcher: 我知道 pt.GetValue(proInfo, null);第一个参数是需要传递返回值的对象,如果在这个地方可以直接new一把EntityNode我肯定不会问你啦。我是想做成一个通用的,在这里我只能得到一个泛型的,你看这句代码:PropertyInfo proInfo = action.Modules.GetType().GetProperty(nameArray[0]);通过action.Modules这个我可以获取到需要赋值和取值的实体对象,但是它是一个泛型(T)的,那么我应该怎样去获取这个T里面的一个类属性对象呢?
@psforever: 给你一段泛型创建的示例代码:
Type generic =typeof(List<>);
generic=generic.MakeGenericType(new Type{typeof(string)};
var list = Activator::CreateInstance(generic);
@Launcher: 我的大概代码是这样的:现在的问题就是下面代码中Get函数的注释部分
public abstract class ActionBase<T> : ActionBase where T : new() { private T modules = new T(); public T Modules { get { return modules; } set { modules = value; } } //赋值的过程
void InitProperties() { string strRequestValue = null; //保存从Request中获取到的参数值 PropertyInfo[] proInfo = Modules.GetType().GetProperties(); foreach (PropertyInfo p in proInfo) { if (p.PropertyType.IsClass) //该属性为一个实体类 { object modulesProObj = null; // 保存当前实体类中包含的实体类属性对象 PropertyInfo[] childProInfo = p.PropertyType.GetProperties(); foreach (PropertyInfo item in childProInfo) { strRequestValue = Request[p.Name + "." + item.Name]; if (strRequestValue != null) { modulesProObj = modulesProObj == null ? Activator.CreateInstance(p.PropertyType) : modulesProObj; item.SetValue(modulesProObj, GetValue(strRequestValue, item), null); } } p.SetValue(Modules, modulesProObj, null); } else if (Request[p.Name] != null) { p.SetValue(Modules, GetValue(Request[p.Name], p), null); } } }
public static object Get(int moduleId, string name) { ActionBase<T> action = GetAction(moduleId) as ActionBase<T>; if (action != null) { if (name.Contains(".")) { string[] nameArray = StringHelper.SplitString(name, "."); PropertyInfo proInfo = action.Modules.GetType().GetProperty(nameArray[0]); if (proInfo.PropertyType.IsClass && proInfo != null) { var pt = proInfo.PropertyType.GetProperty(nameArray[1]); if (pt != null) //???当传递进来的的T为EntityArticle时这里我不知道如何
把获取到它的node属性(EntityNode)转成一个对象带入到下面GetValue方法的第一个参数
return pt.GetValue(??, null); } } else { PropertyInfo pt = action.Modules.GetType().GetProperty(name); if (pt != null) { return pt.GetValue(action.Modules, null); } } } return null; } }
@psforever: 你的意思是 action 有个 Node 属性?
@Launcher: 没有,action就是指ActionBase<T>类对象,我现在传入的T就是上面的EntityArticle,我现在就是需要获取到EntityArticle的属性EntityNode对象
@psforever: 我没时间去读你的代码的逻辑,所以你能不能把你的问题提出来集中在一个示例中,不要让我去理解你的代码想做啥,而是把问题抽象出来。
@Launcher: 其实我的问题也可以演变成:使用反射给实体类属性赋值,当实体类中属性也是一个实体类或者是泛型实体类集合,那么应该怎么利用反射机制来赋值和取值呢?
@psforever:
public class EntityProperty { } public class EntityParameter { } public class EntityProperty<T> { } public class Entity<T> { public EntityProperty Property { get; set; } public EntityProperty<T>[] Properties { get; set; } } public abstract class EntityFactory { public static T CreateEntity<T>() { T t = Activator.CreateInstance<T>(); PropertyInfo[] properties = typeof(T).GetProperties(); foreach (PropertyInfo pi in properties) { Type type = pi.PropertyType; if (type.IsArray) { pi.SetValue(t, Activator.CreateInstance(type, 10), null); } else { pi.SetValue(t, Activator.CreateInstance(type), null); } } return t; } }
不知道是不是你想要的。
@Launcher: 谢谢您的耐心解答。
要实例化这个类
关键代码在这,亲测可用,如果你还不行,联系我找我要测试代码
if (p.PropertyType.IsClass)
{
var type1 = p.PropertyType;
var obj = Assembly.Load(type1.Assembly.FullName).CreateInstance(type1.FullName);
var properties1 = type1.GetProperties();
foreach (var p1 in properties1)
{
p1.SetValue(obj, "111", null);
}
p.SetValue(t, obj, null);
}
@Rich.T: 谢谢了,这种方式应该也可以,但我觉得使用Activator.CreateInstance(p.PropertyType)更好。
可能要 通过Modules来获取属性值
Modules.GetProperty(p.Name);
你要实例化一个对象,然后才能给他的属性赋值。
怎么实例化我也不是很懂,如果出你的类有构造函数就要反射他的构造函数来实例化