4

我是一个初学者,终于开始了解匿名类型。

(请参阅旧帖子What is the return type for a anonymous linq query select?什么是发送此数据的最佳方式?

因此,在 LINQ 查询中,您可以在 linq 查询中形成所需的返回值类型,对吧?似乎这样做的方法是匿名类型,对吗?

有人可以向我解释是否以及何时可以使用 Tuple/Expando 对象吗?他们看起来都很相似?

4

2 回答 2

4

元组和 Expando 对象通常不在 LINQ 中使用。它们都与匿名类型完全不同。

匿名类型通常用于“塑造”LINQ 查询;例如,您可以定义具有string Name属性和int Age属性的类型。

元组是仅充当“对”或“三元组”结构的类型。例如 aTuple<string, int>可以定义,但属性的名称命名为Item1and Item2,而不是Nameand Age。元组通常不用于塑造 LINQ 查询,因为这些属性名称使代码不太清晰。

ExpandoObject 完全不同。它允许您在运行时向现有对象添加属性。

于 2010-06-11T19:53:34.010 回答
3

你没有说明你的问题的上下文,所以我会回答 LinqToObjects 和 LinqToSql。

在 LinqToObjects 中,假设您有一个List<Customer> source.

  //Straight projection.
  //no new instances are created when query is evaluated.
IEnumerable<Customer> result =
  from c in source where c.Name == "Bob"
  select c;

  //Different Type projection
  //a new instance of CustomerName is created
  // for each element in the result when the query is evaluated.
IEnumerable<CustomerName> result =
  from c in source where c.Name == "Bob"
  select new CustomerName() {Name = c.Name};

  //Anonymous Type Projection    
  //a new instance of an anonymous type is created
  // for each element in the result when the query is evaluated.
  //You don't have access to the type's name
  // since the compiler names the type,
  // so you must use var to talk about the type of the result.
var result =
  from c in source where c.Name == "Bob"
  select new {Name = "Bob"};

  //Tuple Projection (same as Different Type Projection)
  //a new instance of Tuple is created
  // for each element in the result when the query is evaluated.
IEnumerable<Tuple<string, int>> result = 
  from c in source where c.Name == "Bob"
  select new Tuple<string, int>(){First = c.Name, Second = c.Id};

在 LinqToSql 中,假设您有一个IQueryable<Customer> db.Customers

  //Straight projection
  //when the query is resolved
  // DataContext.Translate<Customer> is called
  // which converts the private dbReader into new Customer instances.
IQueryable<Customer> result =
  from c in db.Customers where c.Name == "Bob"
  select c;

  //Different Type Projection
  //when the query is resolved
  // DataContext.Translate<CustomerName> is called
  // which converts the private dbReader into new CustomerName instances.
  // 0 Customer instances are created.
IQueryable<Customer> result =
  from c in db.Customers where c.Name == "Bob"
  select new CustomerName() {Name = c.Name};

  //Different Type Projection with a twist
  //when the query is resolved
  // DataContext.Translate<CustomerGroup> is called
  // which converts the private dbReader into new CustomerGroup instances.
  // 0 Customer instances are created.
  //the anonymous type is used in the query translation
  // yet no instances of the anonymous type are created.
IQueryable<Customer> result =
  from c in db.Customers
  group c by new {c.Name, TheCount = c.Orders.Count()} into g
  select new CustomerGroup()
  {
    Name = g.Key.Name,
    OrderCount = g.Key.TheCount,
    NumberInGroup = g.Count()
  };

好的,现在就足够了。

于 2010-06-11T20:22:40.497 回答