在C#中应该如何使用匿名类型?

19

我看过许多有关匿名类型如何工作的介绍,但不确定它们真正有何用处。在设计良好的程序中,匿名类型可以用于解决哪些场景?

7个回答

21

匿名类型与系统设计甚至类级别无关,它们只是开发人员编码时使用的工具。

我甚至不将匿名类型视为类型本身。我主要将它们用作方法级别的匿名元组。如果我查询数据库然后操作结果,我更愿意创建匿名类型并使用它,而不是声明一个完全不会在我的方法范围外使用或知道的全新类型。

例如:

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,匿名类型。它存在是为了让你不必声明另一个类。


你真的需要这个吗?如果你在方法中做了很多事情,以至于需要使用匿名类型,那么你应该重构这个方法。在你的例子中,你查询了数据库,然后修改了结果,对我来说这是两个不同的方法。 - EightyOne Unite
4
我不会修改结果,而是将它们转化为其他形式,以便更容易返回。应该小心不要将代码过度分布在多个方法中,否则代码将变得完全无法阅读,并且由于没有使用匿名类型的能力,会产生很多丑陋的代码或冗余的手动编码类型。 - Omer van Kloeten

9
从 LINQ 实战(第76页第2.6.3节)中得知:匿名类型是快速简单的临时结果的好工具。由于有了临时类型,我们不需要声明类来保存临时结果。
基本上,它们很有用,可以在本地范围内暂时保存信息。任何更多的操作都需要使用反射,并可能成为一个大问题。以上引用书中给出的示例是写入控制台每个运行进程的 id、名称和占用内存量。他们创建了一个匿名类型,将其添加到列表中(所有一条语句),然后使用 ObjectDumper 输出它。因此,代码不再需要单独声明的类来保存 id、名称和内存使用情况,而是全部隐式声明,将代码行数减少到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);

3
最流行的匿名类型用法是在LINQ to SQL查询中指定投影。
这个查询:
from x in db.Table1 select new {x.Column1, Alias2=x.Column2}

将被转换为以下SQL:

SELECT Column1, Column2 AS Alias2 FROM Table1

使用匿名类型,您可以在事先不定义类型的情况下创建临时投影。编译器将为您定义类型。


2
当您创建“使用和丢弃”目的的类型时。这似乎是由于LINQ引起的。它似乎是一种为LINQ查询动态创建具有字段的结构体/类型的方法。仅返回指定字段的结构体/类型。如果没有这个,您将不得不为要检索的每个唯一字段组合声明一个.Net类型。

1

与 Linq 一起使用它们。


0

重要的是要知道,LINQ不强制您使用匿名类型。您也可以在select之后编写普通的对象构造。

var query = from item in database.Items
// ...
select new Person(item.id, item.Name)

这可以避免您进行丑陋的反射编程。


-1

@Wouter:

var query = from item in database.Items
select new Person
{
ID =item.id,
NAME= item.Name
};

其中ID和NAME是你的Person类的真实属性。


那不是匿名类型。 - Joe
这是使用对象初始化器而不是匿名类型。 - Tobi Owolawi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接