首页 新闻 会员 周边

使用反射给实体类的属性赋值(注:实体类属性包含其它实体类)

0
悬赏园豆:50 [已解决问题] 解决于 2012-12-28 10:20
   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的第一个参数需要“设置其属性值得对象”,但是我不知道在这里如何得到这个属性对象

希望能有人指点一下,谢谢!

psforever的主页 psforever | 菜鸟二级 | 园豆:461
提问于:2012-12-27 17:02
< >
分享
最佳答案
1

用 Activator.CreateInstance.

收获园豆:30
Launcher | 高人七级 |园豆:45045 | 2012-12-27 17:09

谢谢了,就是这个了。

psforever | 园豆:461 (菜鸟二级) | 2012-12-28 10:19

谢谢你的解答,我还想请教一下,在取值的时候我应该怎么获取当前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 | 园豆:461 (菜鸟二级) | 2012-12-28 15:43

@psforever: PropertyInfo.GetValue 的第一个参数是将返回其值的对象,也就是说 pt.GetValue(proInfo.null) 是不对的,而是 :

EntityNode node = new EntityNode();

pt.GetValue(node,null);  // 这里的 pt 是 EntityNode 的 Title  属性。

Launcher | 园豆:45045 (高人七级) | 2012-12-28 15:57

@Launcher: 我知道 pt.GetValue(proInfo, null);第一个参数是需要传递返回值的对象,如果在这个地方可以直接new一把EntityNode我肯定不会问你啦。我是想做成一个通用的,在这里我只能得到一个泛型的,你看这句代码:PropertyInfo proInfo = action.Modules.GetType().GetProperty(nameArray[0]);通过action.Modules这个我可以获取到需要赋值和取值的实体对象,但是它是一个泛型(T)的,那么我应该怎样去获取这个T里面的一个类属性对象呢?

psforever | 园豆:461 (菜鸟二级) | 2012-12-28 16:40

@psforever: 给你一段泛型创建的示例代码:

Type generic =typeof(List<>);

generic=generic.MakeGenericType(new Type{typeof(string)};

var list  = Activator::CreateInstance(generic);

Launcher | 园豆:45045 (高人七级) | 2012-12-28 17:16

@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 | 园豆:461 (菜鸟二级) | 2012-12-28 17:51

@psforever: 你的意思是 action 有个 Node 属性?

Launcher | 园豆:45045 (高人七级) | 2012-12-28 17:59

@Launcher: 没有,action就是指ActionBase<T>类对象,我现在传入的T就是上面的EntityArticle,我现在就是需要获取到EntityArticle的属性EntityNode对象

psforever | 园豆:461 (菜鸟二级) | 2012-12-28 18:06

@psforever: 我没时间去读你的代码的逻辑,所以你能不能把你的问题提出来集中在一个示例中,不要让我去理解你的代码想做啥,而是把问题抽象出来。

Launcher | 园豆:45045 (高人七级) | 2013-01-04 09:25

@Launcher: 其实我的问题也可以演变成:使用反射给实体类属性赋值,当实体类中属性也是一个实体类或者是泛型实体类集合,那么应该怎么利用反射机制来赋值和取值呢?

psforever | 园豆:461 (菜鸟二级) | 2013-01-06 00:32

@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 | 园豆:45045 (高人七级) | 2013-01-06 09:43

@Launcher: 谢谢您的耐心解答。

psforever | 园豆:461 (菜鸟二级) | 2013-01-06 15:40
其他回答(3)
0

要实例化这个类

收获园豆:20
Rich.T | 园豆:3440 (老鸟四级) | 2012-12-27 17:09

关键代码在这,亲测可用,如果你还不行,联系我找我要测试代码

 

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

支持(0) 反对(0) Rich.T | 园豆:3440 (老鸟四级) | 2012-12-27 17:40

@Rich.T: 谢谢了,这种方式应该也可以,但我觉得使用Activator.CreateInstance(p.PropertyType)更好。

支持(0) 反对(0) psforever | 园豆:461 (菜鸟二级) | 2012-12-28 10:19
0

可能要 通过Modules来获取属性值

Modules.GetProperty(p.Name);

Qlin | 园豆:2403 (老鸟四级) | 2012-12-27 17:14
0

你要实例化一个对象,然后才能给他的属性赋值。

怎么实例化我也不是很懂,如果出你的类有构造函数就要反射他的构造函数来实例化

茂茂 | 园豆:2892 (老鸟四级) | 2012-12-28 09:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册