【问题标题】:How to access count property of a dynamic type in C# 4.0?如何在 C# 4.0 中访问动态类型的计数属性?
【发布时间】:2011-09-11 06:00:40
【问题描述】:

我有以下方法,它返回一个表示IEnumerable<'a>('a=匿名类型)的动态对象:

    public dynamic GetReportFilesbyStoreProductID(int StoreProductID)
    {
        Report report = this.repository.GetReportByStoreProductID(StoreProductID);

        if (report == null || report.ReportFiles == null)
        {
            return null;
        }

        var query = from x in report.ReportFiles
                    orderby x.DisplayOrder
                    select new { ID = x.RptFileID, Description = x.LinkDescription, File = x.LinkPath, GroupDescription = x.ReportFileGroup.Description };

        return query;
    }

我希望能够访问此 IEnumerable 匿名类型的 Count 属性。我正在尝试使用以下代码访问上述方法,但它失败了:

        dynamic Segments = Top20Controller.GetReportFilesbyStoreProductID(StoreProductID");

        if (Segments.Count == 0)  // <== Fails because object doesn't contain count.
        {
            ...
        }
  • dynamic关键字是如何运作的?
  • 如何访问 IEnumerable 匿名类型的 Count 属性?
  • 有没有办法可以使用这种匿名类型,或者我必须创建一个自定义对象,以便我可以传回强类型的IEnumerable&lt;myObject&gt; 而不是dynamic

如果可以的话,我宁愿不这样做,因为这个方法只在一个地方被调用,而创建一个丢弃的对象似乎有点矫枉过正。

【问题讨论】:

  • 您应该强烈考虑创建真实类型而不是匿名类型并返回IEnumerable。为此目的使用动态会消除静态类型的所有优势。
  • @Chevex,如果 OP 从 public 方法返回这个值,我不明白为什么我们认为它只会被调用一次。
  • @mquander,我完全不同意静态类型即使在一次性情况下也没有优势。如果您建议可以从方法返回匿名类型(作为该类型)会很好,我同意!但你不能。在这种情况下,静态类型仍然无限有用。 (智能感知、编译时安全等)
  • @True,不要争论,但我认为 dynamic 不应该永远用于链接匿名类型。它永远不应该被使用,因为一个人懒得创建一个合适的类型。它应该用于反射、动态调度、COM 或动态脚本。
  • @Chevex,是的,这就是为什么这些是 cmets 而不是答案。 :)

标签: c# reflection dynamic c#-4.0 anonymous-types


【解决方案1】:

您需要显式调用 Enumerable.Count()。

IEnumerable<string> segments =
  from x in new List<string> { "one", "two" } select x;

Console.WriteLine(segments.Count());  // works

dynamic dSegments = segments;

// Console.WriteLine(dSegments.Count());  // fails

Console.WriteLine(Enumerable.Count(dSegments));  // works

请参阅Extension method and dynamic object in c#,了解动态类型不支持扩展方法的原因。

(“d”前缀仅用于示例代码 - 请不要使用匈牙利符号!)

更新:我个人会选择 @Magnus's answer 使用 if (!Segments.Any()) 并返回 IEnumerable&lt;dynamic&gt;

【讨论】:

  • +1 完全忘记了使用 Dynamics 时的注意事项。真的很想知道接受的答案是如何工作的。不过谢谢
  • 完美.. +++++++
【解决方案2】:

从该方法返回的IEnumerable&lt;T&gt; 没有Count 属性,所以我不知道您在说什么。也许你忘了在末尾写ToList() 将其具体化为一个列表,或者你打算在IEnumerable&lt;T&gt; 上调用Count() 方法?

【讨论】:

  • 可能没有静态的Count 属性,但有Count() LINQ 扩展。我认为他的观点是他不知道如何使用返回的动态对象。
  • 好吧,如果他碰巧指的是实际存在的属性或方法,那么他会正确使用它,所以他一定是混淆了一些东西。
  • 是的,我会通知他在 Count 调用中添加括号。
【解决方案3】:

Count()需要枚举完成收集,你可能想要:

if (!Segments.Any()) 
{
}

你的函数应该返回IEnumerable&lt;object&gt;而不是动态

【讨论】:

  • +1 - 我必须尝试一下,但这行得通。虽然我怀疑 OP 会想要返回 IEnumerable 以获取匿名类型的属性。
【解决方案4】:

试试 Linq countusing System.Linq; Segments.Count()

【讨论】:

    【解决方案5】:

    你也可以使用属性长度!

    if (!Segments.Length)
    {
        `enter code here`
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2013-07-12
      相关资源
      最近更新 更多