我已经看到了很多关于匿名类型如何工作的描述,但是我不确定它们是否真正有用。 在精心设计的程序中可以使用匿名类型解决哪些方案?
匿名类型与系统的设计甚至在类级别都没有关系。它们是开发人员在编码时使用的工具。
我什至不将匿名类型视为本身的类型。我主要将它们用作方法级别的匿名元组。如果我查询数据库然后处理结果,我宁愿创建一个匿名类型并使用它,而不是声明一个永远不会在我的方法范围之外使用或得知的全新类型。
例如:
1 2 3 4 5
| var query = from item in database.Items
// ...
select new { Id = item.Id, Name = item.Name };
return query.ToDictionary(item => item.Id, item => item.Name); |
没有人关心`a,匿名类型。它在那里,所以您不必声明另一个类。
从运行中的LINQ(第76页的2.6.3节):
... anonymous types [are] a great tool for quick and simple temporary results. We don't need to declare classes to hold temporary results thanks to temporary types.
基本上,它们对于暂时在本地范围内保存信息很有用。还有更多需要使用反射的问题,并且可能会成为一个很大的问题。他们在上面引用的书中给出的示例是以书面形式编写的,用于控制台id,名称和每个正在运行的进程占用的内存量。他们创建一个匿名类型,将其添加到列表(所有一条语句)中,然后使用ObjectDumper进行输出。因此,代码不再需要单独声明的类来保存所使用的id,名称和内存,而是全部隐式声明,使行数减少到4:
1 2 3 4
| var pl = new List<Object>();
foreach(var p in Process.GetProcesses())
pl.Add(new {p.Id, p.ProcessName, Memory=p.WorkingSet64});
ObjectDumper.Write(pl); |
匿名类型最流行的用途是在LINQ to SQL查询中指定投影。
这个查询
1
| from x in db.Table1 select new {x.Column1, Alias2=x.Column2} |
将转换为以下SQL:
1
| SELECT Column1, Column2 AS Alias2 FROM Table1 |
使用匿名类型,您可以创建临时投影而无需事先为其定义类型。编译器将为您定义类型。
与Linq一起使用。
为"使用和抛出"目的创建类型时。
这似乎是由于LINQ造成的。似乎是一种动态创建具有LINQ查询字段的结构的方法。仅返回具有指定字段的结构/类型。如果不是这样,则必须为每个要检索的字段的唯一组合声明一个.Net类型。
重要的是要知道,LINQ不会强迫您使用匿名类型。选择后还可以编写普通的对象构造。
1 2 3
| var query = from item in database.Items
// ...
select new Person(item.id, item.Name) |
这可以防止您进行丑陋的反射编程。
@Wouter:
1 2 3 4 5 6
| var query = from item in database.Items
select new Person
{
ID =item.id,
NAME= item.Name
}; |
其中ID和NAME是您的Person类的不动产。