首页 新闻 会员 周边

如何动态生成匿名类?Linq里如何实现返回匿名类的呢?

2
悬赏园豆:100 [待解决问题]

Linq 里可以返回匿名类,这个很好用,自己的ORM里也想实现同样的功能,但赋值的时候发现匿名类的属性是Readonly的,晕了,Linq是怎么实现的呢?

简单写个示意代码如下:

简单建个Customer实体类。

class Customer
     {
         public string FirstName { get; set; }
         public string LastName { get; set; }
     }

 做个Select方法:

class Entity<T>
    {
        public static Tresult MySelect<Tresult>(Expression<Func<T, Tresult>> func)
        {
            Type type = typeof(Tresult);
            Tresult t = (Tresult)Activator.CreateInstance(type, new object[type.GetProperties().Length]);

            object someValue = "";// 具体值不写了,只是做个样子
            foreach (PropertyInfo pi in type.GetProperties())
            {
                pi.SetValue(t, someValue, null); // 问题就出在这里了,如果是匿名类的话,没有Set方法。
            }

            return t;
        }
    }

 调用:

var cus = Entity<Customer>.MySelect(s => new { MyName = s.FirstName, YourName = s.LastName });

 

cus是我想要的匿名类,这个没问题,也是我想要的结果。不过在Select中构建这个匿名类时不能用SetValue的方法,说没有Set Method,我查了一下MSDN,里面说匿名类的Property是Readonly的,那这样的话,应该如何进行赋值呢? 是我的出发点错了吗?不用反射的话,有没有其他方法? 

请有经验的朋友帮帮忙,先谢谢了。

-----------------------------------------------------

想到了一个办法,在构建这个类时,就把值赋好了。

代码如下:

object[] objArr = new object[type.GetProperties().Length];
                        for (int i=0;i<type.GetProperties().Length;i++)
                        {
                            objArr[i] = someValue.....
                        }
                        return (T)Activator.CreateInstance(type, objArr);

这样基本满足我的要求了,效率还没测,回头测试一下。大家如果有更好的办法,请补充,谢谢。

AndyLiu的主页 AndyLiu | 初学一级 | 园豆:106
提问于:2012-04-20 20:07
< >
分享
所有回答(3)
-1

不知道你为什么要去set匿名类型的值,TResult 难道不应该是func自己执行的返回值吗,为什么需要你去操心呢。。LINQ以及你的MySelect方法应该是这么实现的:

public static Tresult MySelect<Tresult>(Expression<Func<T, Tresult>> func)
{
      //一些不重要的代码
      return func.Compile()(this.Data); 
}

//其中this.Data是你Entity<T>实例返回T模型的一个属性
水牛刀刀 | 园豆:6350 (大侠五级) | 2012-04-20 23:21
1

试了下用这样就可以了

public static TResult MySelect<TResult>(Expression<Func<T,TResult>> func)
{

  return func.Compile()(Activator.CreateInstance<T>());
}
清風揚諰 | 园豆:197 (初学一级) | 2012-04-21 08:07
0
        private void Test()
        {
            var cus = Entity<Customer>
                .Select(custom => new { MyName = custom.FirstName, YourName = custom.LastName });
        }

        private static TR Select<TR>(Expression<Func<Customer, TR>> expression)
        {
            var someValue = "";// 具体值不写了,只是做个样子

            var custom = new Customer { FirstName = "fuck", LastName = someValue };

            return expression.Compile()(custom);
        }
waninlezu | 园豆:661 (小虾三级) | 2012-04-21 13:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册