【问题标题】:How to pass anonymous type to method as a parameter? [duplicate]如何将匿名类型作为参数传递给方法? [复制]
【发布时间】:2012-01-11 07:17:48
【问题描述】:

可能重复:
What’s the return type of an anonymous class

我正在使用如下查询创建一个匿名类型:

来电代码:

 var query= from p in _db.ExecuteDataSet(SQL).Tables[0].AsEnumerable()
                        select new {
                                       ProductCode = p.Field<string>("PRODUCT_CODE"),
                                       ProductName = p.Field<string>("PRODUCT_NAME")
                                   };
 foreach(var product in query)
 {
     WriteProduct(product);
 }

方法如下:

void WriteProduct(object prod)
{
  //   access the product
}

我无法为WriteProduct 方法获取正确的参数类型。请帮帮我。

【问题讨论】:

  • 匿名类型几乎就是他们所谓的:他们没有名字。如果它没有名字,你就不能引用它。如果您希望能够引用它,请使其成为一个成熟的类或结构。
  • @zneak:匿名类型确实有一个在编译时已知的类型名称。你可以像这样得到它:product.GetType().FullName。这对 OP 没有帮助,但您的评论并不完全正确。

标签: c# linq c#-4.0


【解决方案1】:

是的,你可以。

public class Program
{
    private static void Thing(dynamic other)
    {
        Console.WriteLine(other.TheThing);
    }

    private static void Main()
    {
        var things = new { TheThing = "Worked!" };
        Thing(things);
    }
}

但作为一个小细节,不要!

匿名类型是匿名的是有原因的,它们不是代码中的一等实体,它们更方便。如果一个类型那么重要,那么定义它。

【讨论】:

    【解决方案2】:

    有 3 种方式与匿名类型交谈:

    • 反射(通过obj.GetType().GetProperties()/prop.GetValue(obj, null)等获取属性)
    • dynamic(即obj.ProductCodeobj.ProductType,用于dynamic obj)- 上述优化且更漂亮的版本
    • 示例:请勿使用

    您的WriteProduct 必须使用其中之一;或者:使用匿名类型以外的东西; Tuple&lt;...&gt;,也许是(尽管这往往会让人很难知道数据是什么)——或者适当定义的自定义接口、类或结构。

    【讨论】:

    • “逐个示例”? (我保证不会使用它!)
    • @GeorgeDuckett 有一些讨厌的方法可以滥用(在模块内保证)两个具有相同名称和相同顺序的相同类型的匿名类型将是相同类型的事实。例如,您可以在方法内创建一个孪生值,并使用它来欺骗泛型类型推断,将未知值输入到该类型中。凌乱,真的很脆弱。 pastie.org/2953799
    • 啊,聪明的东西。我绝对不会使用它;看起来真的很像一些很臭的代码!
    【解决方案3】:

    如果我错了,请纠正我,但我认为您应该创建一个临时类来存储产品。

    select new TempProduct {
        productCode = p.Field<string>("PRODUCT_CODE"),
        productName = p.Field<string>("PRODUCT_NAME")
    };
    

    例如这样的类

    public class TempProduct
    {
        public String productCode { get; set; }
        public String productName { get; set; }
    }
    

    【讨论】:

    • +1;我会让名字有首字母大写,即使这是一个使用有限的类。 ProductCode 而不是 productCode
    • 是的,我一开始就是这样的,但是着色可能会让人感到困惑,因为它像一个班级一样着色。但我在这里和你在一起!
    【解决方案4】:

    这不是您所要求的,但您的选择只有两个属性,那么将这两个传递给方法怎么样?

    foreach(var product in query) 
    { 
        WriteProduct(product.ProductCode, product.ProductName); 
    } 
    // ...
    void WriteProduct(string productCode, string productName) 
    { 
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 2018-03-02
      • 2012-12-24
      • 2011-07-03
      • 1970-01-01
      • 2018-05-16
      相关资源
      最近更新 更多