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

问题描述 投票:5回答:5

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

我想把这个匿名类型返回到我的服务层,以便在上面做一些逻辑和东西。

但我不知道如何返回它。

我想我可以这样做

public List<T> thisIsAtest()
{
     return query;
}

但我得到这个错误

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

所以,不知道我缺少什么组件,或者是否是这样的情况。

谅谅

编辑

好吧,我的第一个问题已经解决了,但现在我有一个新的问题,我不知道如何解决,因为我不太了解匿名类型。

我得到了这个错误

不能隐式地将类型'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();

编辑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;
   }

择有此意

Anonymous Types:

a is new{string Prefix}
b is new{ 'a prefix, decimal? marks}
c# .net generics anonymous-types anonymous-methods
5个回答
8
投票

你不能--就这样。你 不能 在自己的作用域之外使用匿名类型,例如,你不能把它们作为方法的返回值。

如果你需要返回它们,你需要定义一个新的具体类来代替匿名类型,并在匿名类型的地方使用它。

参见Rick Strahl的 博文 关于匿名类型的范围划分,请参见《匿名类型的范围划分》。MSDN文档在这里 其中明确指出:"匿名类型有方法范围。

一个匿名类型有方法范围。要在方法边界外传递一个匿名类型,或者一个包含匿名类型的集合,必须先将该类型转为对象。 然而,这就违背了匿名类型的强类型性。如果你必须在方法边界外存储你的查询结果或传递它们,请考虑使用一个普通的命名结构或类来代替匿名类型。

好吧,当然--有一些肮脏的可怕的黑客确实可以返回匿名类型。但如果微软的MSDN AND 乔恩-斯基特不鼓励这种做法,那么--。不干. 根据定义和意图,匿名类型被绑定到它们所定义的方法中。

更新 for chobo2: 我不知道你的数据类型是什么--只是猜测--但假设 "前缀 "是一个int,"标记 "是一个十进制,你可以定义一个新的类。

public class ReturnValue
{
    int prefix { get; set; }
    decimal Marks { get; set; } 
}  

然后你的代码将是一个方法,返回一个... 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();
}

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

     .Select(group => new { prefix = group.Key, marks = .... }

而是创建一个具体类型的实例

     .Select(group => new ReturnValue { prefix = group.Key, marks = .... }

这样一来,你就有了一个具体的类 ReturnValue - 命名为任何你喜欢的类型--然后你可以很容易地返回该类型的列表,并在其他地方使用该类型。


10
投票
public List<T> thisIsAtest<T>()
{
     return query;
}

3
投票

你想从一个常规方法中返回一个匿名类型?我很确定你可以用Reflection来实现,但是没有类型安全和其他一系列的问题。更不用说从调用代码的角度来看,它看起来很奇怪。我想你基本上必须返回对象。

你最好使用一个类或结构,然后把值塞进去。


0
投票

匿名类型是非常有限的,你只能在它们被声明的方法范围内使用它们。

你可以把它们作为普通的对象传回来,但是你会失去类型信息。我见过一些传递匿名类型的解决方案;但他们使用反射在稍后的点检索属性。


0
投票

如果你把通用列表声明为一个全局变量,你就不需要使用return。我在我的代码中使用了return函数,只是因为marc_s说我不能使用。

 public static class Globals
    {
        public static List<string> CurPart = new List<string>();
    }
    public List<string> MSQueryRead1DArray(string sql, string db)
    {
        return Globals.CurPart;
    }
© www.soinside.com 2019 - 2024. All rights reserved.