在C#中返回匿名types

我有一个查询返回一个匿名types,查询是在一个方法。 你怎么写这个:

public "TheAnonymousType" TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return "TheAnonymousType"; } } 

你不能。

您只能返回objectobject容器,例如IEnumerable<object>IList<object>

你可以返回dynamic ,它会给你一个匿名types的运行时检查版本,但只能在.NET 4+中使用

你不能返回匿名types。 你能创build一个可以返回的模型吗? 否则,你必须使用一个object

这是Jon Skeet撰写的关于这个主题的文章

来自文章的代码:

 using System; static class GrottyHacks { internal static T Cast<T>(object target, T example) { return (T) target; } } class CheesecakeFactory { static object CreateCheesecake() { return new { Fruit="Strawberry", Topping="Chocolate" }; } static void Main() { object weaklyTyped = CreateCheesecake(); var stronglyTyped = GrottyHacks.Cast(weaklyTyped, new { Fruit="", Topping="" }); Console.WriteLine("Cheesecake: {0} ({1})", stronglyTyped.Fruit, stronglyTyped.Topping); } } 

或者,这里是另一个类似的文章

或者,正如其他人正在评论,你可以使用dynamic

当需要返回时,可以使用Tuple类作为匿名types的替代:

注意:元组最多可以有8个参数。

 return Tuple.Create(variable1, variable2); 

或者,从原始post的例子来看:

 public List<Tuple<SomeType, AnotherType>> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select Tuple.Create(..., ...) ).ToList(); return TheQueryFromDB.ToList(); } } 

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

三个选项:

选项1:

 public class TheRepresentativeType { public ... SomeVariable {get;set;} public ... AnotherVariable {get;set;} } public IEnumerable<TheRepresentativeType> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

选项2:

 public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

你可以迭代它作为对象

备选案文3:

 public IEnumerable<dynamic> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; //You may need to call .Cast<dynamic>(), but I'm not sure } } 

你将能够迭代它作为一个dynamic的对象,并直接访问他们的属性

C#编译器是一个两阶段编译器。 在第一阶段,它只检查命名空间,类层次结构,方法签名等。方法体只在第二阶段被编译。

在编译方法体之前,匿名types不会被确定。

所以编译器在第一阶段没有办法确定方法的返回types。

这就是为什么匿名types不能用作返回types的原因。

正如其他人所build议的,如果您使用.net 4.0或更高版本,您可以使用Dynamic

如果我是你,我可能会创build一个types,并从该方法返回该types。 这样,维护你的代码和更具可读性的未来程序员将变得非常容易。

 public List<SomeClass> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new SomeClass{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.ToList(); } } public class SomeClass{ public string SomeVariable{get;set} public string AnotherVariable{get;set;} } 

创build自己的类并查询它是我知道的最好的解决scheme。就我所知,不能在另一个方法中使用匿名types的返回值,因为它不会被识别。但是,它们可以用在相同的方法。 我曾经把它们作为IQueryableIEnumerable返回,尽pipe它仍然不能让你看到匿名typesvariables的内部。

当我试图重构一些代码时,我碰到类似这样的东西,你可以在这里检查: 重构和创build单独的方法

在C#7中,我们可以使用元组来实现这一点:

 public List<(int SomeVariable, string AnotherVariable)> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.Select(s => (SomeVariable = s.SomeVariable, AnotherVariable = s.AnotherVariable)).ToList(); } } 

您可能需要安装System.ValueTuple nuget包。

在这种情况下,您可以返回对象列表。

 public List<object> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB ; } }