2012-04-09 171 views
61

我有一个查询返回一个匿名类型,查询在方法中。你如何写这个:在C中返回匿名类型#

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

     return "TheAnonymousType"; 
    } 
} 
+4

为什么你想要返回一个匿名类型?你怎么可能在其他地方使用这个结果呢? – Yuck 2012-04-09 12:43:15

+0

[我怎样才能从方法返回匿名类型?](http://stackoverflow.com/questions/55101/how-can-i-return-an-anonymous-type-from-a-method) – nawfal 2014-02-03 09:21:35

+4

@Yuck如果你要返回json或c#类型无关紧要的东西 – aw04 2014-08-04 19:02:44

回答

61

你不能。

您只能返回object或对象的容器,例如, IEnumerable<object>,IList<object>

+36

或'动态'。这使得它可以轻松处理。 – vcsjones 2012-04-09 12:43:22

+0

啊好的,所以你只能在方法内使用匿名类型,而不能作为返回值? – frenchie 2012-04-09 12:43:56

+2

@frenchie:是的,只在会员的身体内。如果你想返回它 - 使它成为一个众所周知的类型。 – abatishchev 2012-04-09 12:45:03

20

您不能返回匿名类型。你能创建一个可以返回的模型吗?否则,您必须使用object。从文章

Here is an article written by Jon Skeet on the subject

代码:

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);    
    } 
} 

Or, here is another similar article

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

+5

当然,我可以创建一个类型;我期待避免这样做。 – frenchie 2012-04-09 12:43:17

+0

第一个链接已经死了,难道你不知道它是否被转移到其他地方? – 2016-09-13 20:48:23

+0

@Rémi我已更新链接 – 2016-09-13 20:55:27

1

您可以在此情况下,返回一个对象名单。

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

     return TheQueryFromDB ; 
    } 
} 
31

您可以返回dynamic,这将给你的匿名类型的运行时检查版本,但仅在.NET 4+

8

三个选项:

选项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 
    } 
} 

,你将能够重复它作为一个动态对象并访问其属性直接

2
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;} 
} 

创建自己的类并且查询它是我知道的最佳解决方案。据我所知,不能在另一个方法中使用匿名类型的返回值,因为它不会被识别。但是,它们可以用于相同的方法。 我曾经把它们作为IQueryableIEnumerable返回,尽管它仍然不让你看到匿名类型变量的内部。

我碰上,而我试图重构一些代码之前是这样的,您可以点击此处查看:Refactoring and creating separate methods

8

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

直到方法体被编译后才确定匿名类型。

因此编译器无法确定第一阶段中该方法的返回类型。

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

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

如果我是你,我可能会创建一个类型并从该方法返回该类型。这样,维护代码和更具可读性的未来程序员就很容易。

16

您可以使用元组类作为返回时,一个匿名类型的替代品是必要的:

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

return Tuple.Create(variable1, variable2); 

或者,从原帖的例子:

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

4

在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包。