在C#中返回匿名types
我有一个查询返回一个匿名types,查询是在一个方法。 你怎么写这个:
public "TheAnonymousType" TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return "TheAnonymousType"; } }
你不能。
您只能返回object
或object
容器,例如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的返回值,因为它不会被识别。但是,它们可以用在相同的方法。 我曾经把它们作为IQueryable
或IEnumerable
返回,尽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 ; } }