【问题标题】:How should anonymous types be used in C#?在 C# 中应该如何使用匿名类型?
【发布时间】:2008-09-07 18:34:32
【问题描述】:

我看过很多关于匿名类型如何工作的描述,但我不确定它们如何真正有用。在精心设计的程序中可以使用匿名类型来解决哪些场景?

【问题讨论】:

    标签: c# anonymous-types


    【解决方案1】:

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

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

    例如:

    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,匿名类型。它在那里,因此您不必声明另一个类。

    【讨论】:

    • 你需要这个吗?当然,如果你在你的方法中做了这么多,它需要一个匿名类型,那么你应该重构这个方法。在您的示例中,您查询数据库,然后修改结果,..这对我来说是 2 个单独的方法。
    • 我没有修改结果,而是将它们转换成其他更容易返回的形式。应该注意不要将他们的代码过度分布在多个方法上,因为这会使代码完全不可读和创建,因为无法使用匿名类型,很多丑陋的代码或冗余的手动编码类型。
    【解决方案2】:

    来自 LINQ in action(第 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
      

      使用匿名类型,您可以创建临时投影,而无需事先为其定义类型。编译器会为你定义类型。

      【讨论】:

        【解决方案4】:

        当您为“使用和抛出”目的创建类型时。 这似乎是由于LINQ。似乎是一种为 LINQ 查询动态创建具有字段的结构的方法。仅返回具有指定字段的结构/类型。如果不是这样,您必须为您希望检索的每个唯一字段组合声明一个 .Net 类型。

        【讨论】:

          【解决方案5】:

          将它们与 Linq 一起使用。

          【讨论】:

            【解决方案6】:

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

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

            这可以防止你使用丑陋的反射编程。

            【讨论】:

              【解决方案7】:

              @Wouter:

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

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

              【讨论】:

              • 那不是匿名类型
              • 这是使用对象初始化器而不是匿名类型
              猜你喜欢
              • 2017-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-21
              相关资源
              最近更新 更多