none
linq 返回值的类型的问题 RRS feed

  • 问题

  • 怎么样才能确定linq返回值的类型呢?

     

    比如说:

    public ??? GetUserList()
    {
       var ret = from c in t.HL_User
               where (c.UserID != 0 && c.UserName != "")
               select new { UserName =c.UserName,UserID=c.UserID };
    
       return ret;
    };
    

    这时候GetUser函数返回的值的类型应该是什么呢?

    2010年9月16日 8:13

答案

  • 匿名类型是用于方法中临时需要使用类的时候用的,设计的时候并没有考虑会用在不同的方法间,因此一般不会这样用,但不代表不能用

     

    这个要分情况:

    在.NET 3.5中:

    因为不支持协变,所以即使方法类型设为IEnumerable<object>,编译也是通不过的,只能设为object,可是调用方就算调用成功,由于不知道具体类型,无法强转,还是不能使用。

    所以,在.NET 3.5中,无法使用。

     

    在.NET 4.0中:

    因为支持了协变,所以可以允许用IEnumerable<object>作为返回类型,但相对于object,改进点只是能识别到子元素,但子元素还是object类型,依然访问不了UserName,UserID属性。

    还好,.NET 4.0有了DLR,所以可以使用IEnumberable<dynamic>,这样就能正常使用了。

     

    但是,还是开头一句话。匿名类型的设计,是没有考虑到方法间的传递的,所以该定义个类型还是定义一下吧。


    Love Your Neighbor as Yourself
    • 已标记为答案 Mog Liang 2010年9月23日 8:39
    2010年9月17日 5:49

全部回复

  • IQueryable<HL_User>

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2010年9月16日 17:37
    版主
  • IQueryable<object>

    select new { UserName =c.UserName,UserID=c.UserID };

    此处 new 创建了一个匿名类。 

    2010年9月17日 3:51
  • 问题就在于这里,这个匿名类,函数返回的时候,返回值类型应该填什么呢?

    2010年9月17日 3:59
  • 返回 IQueryable<object>
    2010年9月17日 5:00
  • 匿名类型是用于方法中临时需要使用类的时候用的,设计的时候并没有考虑会用在不同的方法间,因此一般不会这样用,但不代表不能用

     

    这个要分情况:

    在.NET 3.5中:

    因为不支持协变,所以即使方法类型设为IEnumerable<object>,编译也是通不过的,只能设为object,可是调用方就算调用成功,由于不知道具体类型,无法强转,还是不能使用。

    所以,在.NET 3.5中,无法使用。

     

    在.NET 4.0中:

    因为支持了协变,所以可以允许用IEnumerable<object>作为返回类型,但相对于object,改进点只是能识别到子元素,但子元素还是object类型,依然访问不了UserName,UserID属性。

    还好,.NET 4.0有了DLR,所以可以使用IEnumberable<dynamic>,这样就能正常使用了。

     

    但是,还是开头一句话。匿名类型的设计,是没有考虑到方法间的传递的,所以该定义个类型还是定义一下吧。


    Love Your Neighbor as Yourself
    • 已标记为答案 Mog Liang 2010年9月23日 8:39
    2010年9月17日 5:49
  • 你的这个代码返回的是匿名类型的对象。既然是匿名类型,自然也就不可能知道类型的名字了。这名字貌似是由编译自动确定的,想在代码中使用,估计是没戏的。不过,你的这个问题,到时有办法可以解决,那就是使用命名类型。

    public IQueryable<UserExpress> GetUserList()
    {
      IQueryable<UserExpress> ret = from c in t.HL_User
          where (c.UserID != 0 && c.UserName != "")
          select new UserExpress{ UserName =c.UserName,UserID=c.UserID };
      return ret;
    };
    

    其中UserExpress是一个自定义的类,此类起码应该包含UserName和UserID这两个属性,否则编译将不通过。
    另外,返回IQueryable<object>这种结果虽然可行,但想要访问UserName和UserID的值,就比较不容易了。
    因为,你还得进行类型转换,而转换的时候,还是不知道该转换成什么类型的。是不是挺棘手的?

    2010年9月17日 5:55