2010-06-30 52 views
1
如何返回匿名类型

可能重复:
LINQ to SQL: Return anonymous type?同时使用LINQ

是否有任何人知道如何返回匿名类型。我正在使用Linq,我需要返回以下代码

private <What's the return type to be provided here> SampleLinq(Int32 Num) 
    { 
     var query = (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId }); 
     return (query)  

    } 
+0

Dup:http://stackoverflow.com/questions/1070526/how-to-return-anonymous-type-from-c-method-that-uses-linq-to-sql-closed – Krunal 2010-06-30 12:29:44

+0

@Krunal - 那一个作为我使用的那个的副本关闭。 – ChrisF 2010-06-30 12:32:16

+0

@ChrisF - 是的,知道的。但让OP看到一切。 – Krunal 2010-06-30 12:34:10

回答

0

您不能从方法返回匿名类型。

您可以创建一个简单的类来包装匿名类型,但您仍然需要一个类(或投到object)。

请记住,如果你投到object就没有办法回避。你需要反射来读取任何数据。

4

很抱歉地说,但您不能将方法范围外的匿名类型返回。

这是另一种方式来获得anonmous型

// Method that returns anonymous type as object 
object ReturnAnonymous() 
{ 
    return new { City="Prague", Name="Tomas" }; 
} 

// Application entry-point 
void Main() 
{ 
    // Get instance of anonymous type with 'City' and 'Name' properties 
    object o = ReturnAnonymous(); 

    // This call to 'Cast' method converts first parameter (object) to the 
    // same type as the type of second parameter - which is in this case 
    // anonymous type with 'City' and 'Name' properties 
    var typed = Cast(o, new { City="", Name="" }); 
    Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City); 
} 

// Cast method - thanks to type inference when calling methods it 
// is possible to cast object to type without knowing the type name 
T Cast<T>(object obj, T type) 
{ 
    return (T)obj; 
} 

你可以用它仅适用于一个组件类型(来自两个不同的组件两个匿名类型将在内部被编译成两个不同的类型,而且不能使用这个技巧进行转换)。

1

你不能那样做。这就是为什么它被称为匿名。它没有名字。但你总是可以将它转换为object

0
private object SampleLinq(Int32 Num) 
{ 
return (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId }); 
} 
+0

但如何将对象重新转换为var以获取属性作为对象不包含getenumerator的公共定义? – user403320 2010-06-30 12:59:23

+1

如果没有额外的方向,例如FirstOrDefault(),查询将返回一个IEnumerable <>。然后你必须使用Reflection来找出如何使用它。 – GalacticCowboy 2010-06-30 13:01:11

+0

@renjithmaxy - “var”!=“<我的匿名类型>”。一个* var *在编译时仍然是强类型的。 – GalacticCowboy 2010-06-30 13:03:39

1

好了,你不能真正做到这一点,但here's a hack这一点。

+2

如果您提供的链接死亡,最好至少添加简短的黑客说明。 – jpierson 2011-04-12 14:37:24

-1

这取决于你想要做什么与返回值。

  • 如果您打算将其绑定在UI 你可以重新运行 的IEnumerableIQueryable的

  • 如果您打算在返回值使用反射如果您使用EF的Linq只返回类型的对象

  • 如果您使用C#4.0你可以返回 动态类型

  • 以SQL进一步加入包含您的匿名类型的查询,您可以使用 技术替代具体的类别 并使用具体的占位符 。有关这个 技术的更多细节,我可以提供一些帮助。

正如其他人所提到的,你应该真的质疑返回匿名类型是否是解决手头问题的最好方法。通常情况下,通常会有更好的基于模式的方法,可能需要更多的编码,但可能导致更优雅的设计。这就是说,我相信有合法的情况下,如数据绑定,其中返回的匿名类型实例可以完全接受。

UPDATE: 只是一个有趣的小知识,我想分享的情况下,这些阅读不知道。匿名类型对于它们的属性名称和类型是唯一的,所以假设您有方法A和方法B,您都可以通过执行类似下面的代码来创建一个名为Name的单个字符串类型属性的匿名类型。

public object A() 
{ 
    return new { Name = "Cid" } 
} 

public object B() 
{ 
    return new { Name = "Galuf" } 
} 

public void Test() 
{ 
    System.Diagnostics.Trace.Assert(A().GetType() == B().GetType()); 
} 

现在虽然这种类型是在两个不同的地方定义的编译器只产生仅仅是因为它们都具有相同的属性由属性类型和属性名称定义创建一个单一的共享类型。在这方面,属性可以被认为是匿名类型的一种签名。利用这些知识,可以使用不同的技术来反省已经转换为对象或使用动态关键字延期的匿名类型实例。正如Linq对静态Enumerable和Queryable类中的方法所做的那样,通过使用泛型方法也可以使用匿名类型。通过这种方式,您可以创建任何给定匿名类型的新实例,而无需使用反射。诀窍在于,您必须使用匿名类型的实例传递给方法才能通过泛型方法来推断类型。如果任何人对这些主题感兴趣,因为它们适用于原始海报问题,请留下评论,我可以尝试澄清其中一些技巧。

+2

真的!没有评论来解释倒票? – jpierson 2011-04-12 14:36:16

+1

+1我从来不知道这些类型可能是平等的! downvote可能是因为你的'技巧是,虽然你必须使用匿名类型的实例传递给方法,以便通过泛型方法来推断类型。如果有人对这些主题感兴趣,因为它们适用于原始海报问题,请留下评论,我可以尝试澄清其中一些技巧。“而不是写它是什么。 – nawfal 2013-02-04 08:05:03

3

返回动态类型:

 public static dynamic getCustomer() 
{ 
    ..... 
    var x = from c in customers 
      select new {Fname = c.FirstName}; 

    return x; 
} 

static void Main(string[] args) 
{ 
    dynamic x = getCustomer(); 
    Console.WriteLine(Enumerable.First(x).Fname); 
    Console.ReadKey(); 
} 
0

你从黑客看到这些问题的答案是大量的工作只是通过一个方法边界得到一个匿名类型。你不应该这样做。如果你需要从方法中传回某些东西,你应该传递具体的类型。

+0

@Mathew - 一般来说,我会同意你的看法,但是在数据绑定的情况下,目标属性(例如DataContext)只是类型对象,绑定在运行时才会真正绑定。例如,返回一个IEnumerable可能是有用的,该枚举枚举了一个匿名类型的实例,该类型的行为就像给定集合的readonly wrappers/ViewModels一样。所以在某些情况下,我认为允许匿名类型的返回实例是有意义的。 – jpierson 2011-04-12 14:45:45

+0

@jpierson - 当然,我认为总是有例外的规则。我希望在这种情况下,这可能是其中一种情况,但在您试图通过代码访问这些成员的情况下,是时候从匿名切换到静态类型的实例。 – 2011-04-12 15:10:26

+0

@Mathew - 同意,就像你在代码中使用反射来获取值时一样。可能有一些精简的例子,它可能是合法的,但除此之外,你真的试图用静态类型语言进行动态编程。现在使用动态关键字,我可以看到一些C#开发人员可能会开始对使用动态样式编程有点古怪,但是过多地使用强类型语言(如C#)的好处很快就会变得不必要的分歧。 – jpierson 2011-04-14 05:31:21