如何从匿名类型引用项目 [英] how to refer to an item from anonymous type

查看:166
本文介绍了如何从匿名类型引用项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码

var results =   (from c in Customers  
                    join o in Orders  
                    on c.Id equals o.CustomerId  
                    join p in Products  
                    on p.Id equals o.ProductId  
                    select new   
                    {  
                        CustomerId = c.Id,     // this is a GUID  
                        OrderId = o.Id,        // this is a GUID    
                        ProductName = p.ProductName,  
                     }).ToList();  

假设我要获取订购名称为foo的产品的所有客户ID的列表 我的问题是,由于它是匿名类型,如何在要对结果运行的任何Linq查询中引用产品名称?

解决方案

var filteredResults = results.Where(r => r.ProductName == "X");

编译器的类型推断将为您解决这个问题.您问题的完整答案:

var customerIds = results
    .Where(r => r.ProductName == "X")
    .Select(r => r.CustomerId)
    .Distinct()
    .ToList();

var customerIds = (from r in results
                  where r.ProductName == "X"
                  select r.CustomerId)
    .Distinct()
    .ToList();

编辑

关于类型推断的一些思考

要从称为list的字符串序列中选择长度,可以使用经典的静态方法语法或作为扩展方法来调用Select:

Enumerable.Select<string, int>(list, s => s.Length)
list.Select<string, int>(s => s.Length)

感谢类型推断,您不需要类型参数:

Enumerable.Select(list, s => s.Length)
list.Select(s => s.Length)

在这种情况下,编译器可以通过查看方法参数来证明类型参数是stringint,并且它代表您提供这些类型参数,而无需您将其键入源代码.

对于匿名类型,您不能提供第一个类型参数,因为该类型没有名称供您在源代码中使用(毕竟,匿名"是什么意思:没有名称"). (因此,您可以看到匿名类型和类型推断既是实现linq的关键条件,又是紧密相关的先决条件.)

如果您查看上述匿名类型示例的IL,则会看到编译器实际上为该类型指定了一个名称(其中包含在C#标识符中非法的字符).当您调用Select时,编译器从可枚举(IEnumerable<CrazilyNamedAnonymousType>)的类型推断出,第一个type参数应该是匿名类型,并且像字符串示例一样,它代表您提供该值.

I have code like this

var results =   (from c in Customers  
                    join o in Orders  
                    on c.Id equals o.CustomerId  
                    join p in Products  
                    on p.Id equals o.ProductId  
                    select new   
                    {  
                        CustomerId = c.Id,     // this is a GUID  
                        OrderId = o.Id,        // this is a GUID    
                        ProductName = p.ProductName,  
                     }).ToList();  

Let's say I want to get a list of all customer Ids that orders a product that has name = foo My problem is that because its an anonymous type, how can I refer product name in any Linq query that I want to run on results?

解决方案

var filteredResults = results.Where(r => r.ProductName == "X");

The compiler's type inference takes care of it for you. The complete answer to your question:

var customerIds = results
    .Where(r => r.ProductName == "X")
    .Select(r => r.CustomerId)
    .Distinct()
    .ToList();

or

var customerIds = (from r in results
                  where r.ProductName == "X"
                  select r.CustomerId)
    .Distinct()
    .ToList();

EDIT

Some musings on type inference

To select the lengths from a sequence of strings called list, you can call Select either using classic static method syntax or as an extension method:

Enumerable.Select<string, int>(list, s => s.Length)
list.Select<string, int>(s => s.Length)

Thanks to type inference, you don't need the type arguments:

Enumerable.Select(list, s => s.Length)
list.Select(s => s.Length)

In this case, the compiler can prove that the type arguments are string and int by looking at the method arguments, and it supplies these type arguments on your behalf without your having to type them into the source code.

For anonymous types, you can't provide the first type argument, because the type doesn't have a name for you to use in the source code (that's what "anonymous" means, after all: "without a name"). (You can see therefore that anonymous types and type inference were both critical -- and closely related -- prerequisites to implementing linq in the first place.)

If you check out the IL for the anonymous type example above, you'll see that the compiler has in fact given the type a name (which contains characters that are illegal in C# identifiers). When you call Select, the compiler deduces from the type of the enumerable (IEnumerable<CrazilyNamedAnonymousType>) that the first type argument should be the anonymous type, and, as with the string example, it supplies that value on your behalf.

这篇关于如何从匿名类型引用项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆