如何在C#中返回通用列表集合?

cho*_*bo2 5 .net c# generics anonymous-methods anonymous-types

我有一些linq to sql方法,当它执行查询时,它返回一些匿名类型.

我想将该匿名类型返回到我的服务层,以便对其进行一些逻辑和操作.

我不知道如何归还它.

我以为我能做到这一点

public List<T> thisIsAtest()
{
     return query;
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了这个错误

Error   1   The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)

所以不确定我错过了什么组件,或者甚至是不是这样.

谢谢

编辑

好吧,我的第一个问题已经解决,但现在我遇到了一个新问题,我不确定如何修复,因为我对匿名类型不太了解.

我收到这个错误

无法将类型'System.Collections.Generic.List'隐式转换为'System.Collections.Generic.List

这是查询

   DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0)
       .GroupBy(u => new { u.Table.Prefix })
       .Select(group => new { prefix = group.Key, 
                              Marks = group.Sum(item => (item.Mark * item.Weight) / item.OutOFF) })
       .ToList();
Run Code Online (Sandbox Code Playgroud)

编辑2

public class ReturnValue
{
   string prefix { get; set; }
   decimal? Marks { get; set; } 
}

public List<ReturnValue> MyTest(Guid userId)
{
   try
   {
       var result = dbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0).GroupBy(u => new { u.Table.Prefix })
       .Select(group => new { prefix = group.Key, Marks = group.Sum(item => (item.Mark * item.Weight) / item.OutOFF) }).ToList();
       return result;
   }
   catch (SqlException)
   {
       throw;
   }
Run Code Online (Sandbox Code Playgroud)

选择中有这个

Anonymous Types:

a is new{string Prefix}
b is new{ 'a prefix, decimal? marks}
Run Code Online (Sandbox Code Playgroud)

Yur*_*ich 9

public List<T> thisIsAtest<T>()
{
     return query;
}
Run Code Online (Sandbox Code Playgroud)


mar*_*c_s 8

你不能 - 期间.您不能在自己的范围之外使用匿名类型,例如,您不能将它们作为方法的返回值返回.

如果需要返回它们,则需要定义一个新的具体类而不是匿名类型,并在匿名类型的位置使用它.

请参阅Rick Strahl 关于匿名类型范围的博客文章,并在此处查看MSDN文档,其中明确指出:

匿名类型具有方法范围.要在方法边界外传递匿名类型或包含匿名类型的集合,必须先将类型转换为对象. 然而,这打败了匿名类型的强类型.如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型.

好的,确定 - 确实有很多糟糕的黑客确实会返回匿名类型.但是,如果微软的MSDN Jon Skeet不鼓励这种做法,那么 - 就是不要这样做.根据定义和意图,匿名类型绑定到它们所定义的方法.

更新 chobo2:我不知道你的数据类型是什么 - 只是猜测 - 但假设"prefix"是一个int而"marks"是一个小数,你可以定义一个新类:

public class ReturnValue
{
    int prefix { get; set; }
    decimal Marks { get; set; } 
}  
Run Code Online (Sandbox Code Playgroud)

然后你的代码将是一个返回List<ReturnValue>:

public List<ReturnValue> thisIsAtest()
{
   DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0)
     .GroupBy(u => new { u.Table.Prefix })
     .Select(group => new ReturnValue 
                          { prefix = group.Key, 
                            Marks = group
                              .Sum(item => (item.Mark * item.Weight) / item.OutOFF) })
     .ToList();
}
Run Code Online (Sandbox Code Playgroud)

这里的关键是:在您的.Select方法中,而不是创建匿名类型的新实例:

     .Select(group => new { prefix = group.Key, marks = .... }
Run Code Online (Sandbox Code Playgroud)

您创建具体类型的实例:

     .Select(group => new ReturnValue { prefix = group.Key, marks = .... }
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您将拥有一个具体的类ReturnValue- 您喜欢的任何名称 - 然后您可以轻松返回该类型的列表,并在其他地方使用该类型.

  • @Jason:是的,理论上 - 但是这会破坏所有类型的安全性和一切.不要这样做 - 只需创建一个真正的具体类,如果你需要返回它 - 更容易和更清洁. (2认同)