【问题标题】:Why doesn't the Lookup that results from GroupBy have Lookup properties?为什么 GroupBy 产生的 Lookup 没有 Lookup 属性?
【发布时间】:2015-05-05 02:24:28
【问题描述】:

我正在尝试理解 System.Linq.Lookup 类。调用GetType()时,显示如下:

System.Linq.Lookup`2+Grouping[System.Object,System.Data.DataRow]
  • 反勾号是什么意思?
  • 2+ 是什么意思?
  • 2+ 后面的 Grouping 类是什么?
  • 进一步,在Fiddle的Inspect()方法中,为什么lookupKey属性而不是CountItem属性?

最终目标是学习如何将它绑定到嵌套的 ASP.NET 中继器。我们已经成功地将结果转换为Dictionary<string, DataTable>。不过,我们怀疑,一旦我们了解了它的结构,就可以将目录绑定到 GroupedEnumerable

Fiddle

public static class Program
{
    public static void Main()
    {
        var dt = GetData();
        var enumerable = dt.AsEnumerable();
        var grouped = enumerable.GroupBy(dr => dr["Name"]);
        Inspect(grouped);
    }

    public static void Inspect(IEnumerable<IGrouping<object, DataRow>> grouped)
    {
        LogType("grouped", grouped);

        var lookup = grouped.FirstOrDefault();
        LogType("lookup", lookup);
        LogType("key", lookup.Key);

        var item = lookup.FirstOrDefault();
        LogType("item", item);
    }

    public static void LogType(string label, object v)
    {
        Console.WriteLine("\n" + label.PadRight(10) + v.GetType());
    }

    public static DataTable GetData()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("StartDate");
        dt.Columns.Add("EndDate");
        for(var i = 0; i < 10; ++i)
        {
            var row = dt.NewRow();
            row["Name"] = i % 2;
            row["StartDate"] = DateTime.Now;
            row["EndDate"] = DateTime.Now;
            dt.Rows.Add(row);
        }
        return dt;
    }
}

输出

grouped   System.Linq.GroupedEnumerable`3[System.Data.DataRow,System.Object,System.Data.DataRow]

lookup    System.Linq.Lookup`2+Grouping[System.Object,System.Data.DataRow]

key       System.String

item      System.Data.DataRow

编辑

Forked FiddleGroupedEnumerable 检索值。

用我自己的话回答:

  • 反勾号是什么意思? 反勾号表示一个类采用的类型参数的数量。在这种情况下,它表示Lookup 类采用两个类型参数。
  • 2+ 是什么意思? 2 属于后面的勾,而不是+。加号表示我们正在访问一个嵌套在另一个类中的类。在这种情况下,这意味着我们正在访问嵌套在 Lookup 类中的 Grouping 类。
  • 2+ 后面的 Grouping 类是什么? 这是一个嵌套在 Lookup 中的类。
  • 进一步,在 Fiddle 的 Inspect() 方法中,为什么 lookup 具有 Key 属性而不是 CountItem 属性? lookup 具有 Key 属性因为它不是Lookup;这是一个嵌套在 Lookup 中的 Grouping

【问题讨论】:

    标签: c# linq


    【解决方案1】:
    System.Linq.Lookup`2+Grouping[System.Object,System.Data.DataRow]
    

    System.Linq.Lookup`2 在 C# 中表示为 System.Linq.Lookup&lt;T,U&gt;(反引号表示该类是泛型的,数字是泛型参数的数量)。

    +Grouping 表示在System.Linq.Lookup`2 类内部定义了一个类,称为Grouping

    方括号内的两种类型是泛型 (System.Linq.Lookup) 关闭的两种类型。

    所以用 C# 编写的完整类型如下所示:

    System.Linq.Lookup<object, System.Data.DataRow>.Grouping
    

    该类型不需要Items 属性,因为它实现了IEnumerable,这意味着可以迭代该类型本身(就像任何其他IEnumerable,例如List&lt;T&gt;)。

    并非所有列表/集合都具有Count 属性,没有任何内容表明它们必须这样做。您可以通过调用Count() 扩展方法来获取计数,但这可能会导致整个枚举被迭代,这可能会或可能不会有显着的性能成本。

    【讨论】:

    • 一个类被定义在另一个类内部是什么意思?这是否意味着它是一个在另一个类中有定义的公共类?父类的行为是否有点像命名空间?
    • 在一个类内部,你可以定义另一个类。在同一个空间中你可以声明一个方法或属性,你也可以声明另一个类型。但是,这只能进行一层深,因此您不能将一个类嵌套在另一个嵌套在第三个类中的类中。在 C# 中,引用该类的语法与如果它是另一个命名空间没有任何不同,但在 CLR 中,它以不同的方式指定(即+ 字符)。
    • 看着你的小提琴,回答为什么你需要 using 语句来编译代码的问题,这是因为你正在使用扩展方法。为了使用扩展方法,必须使用using 语句“导入”包含定义扩展方法的类型的命名空间。同样的原因,如果您删除using System.Linq,您的收藏集将无法再使用很多方法(例如Count()Select()Where() 等)。
    • 但奇怪的是,据我所知,System.Data.DataSetExtensions 是一个程序集而不是命名空间。我们应该能够使用System.Data。有点奇怪。另见:stackoverflow.com/questions/28267788/…
    【解决方案2】:

    这是 CLR 标准类型语法。

    • `2 表示该类型有两个泛型参数。
    • + 表示嵌套在另一个类型中的类型。

    在这种情况下,它告诉您 Grouping class 嵌套在具有两个泛型参数的 Lookup 类中。

    source 可以看出,它定义的唯一公共属性是Key

    【讨论】:

    • 如果我们呼叫lookup,为什么我们会到达Grouping 而不是lookup?在我看来,如果我们调用lookup.FirstOrDefault().Key,我们应该只访问Grouping
    • 啊哈。我得到它。父 Lookup 类的行为有点像命名空间。实际类型是Grouping。它的定义恰好嵌套在Lookup 中。这是有道理的。我以为类型是Lookup 而我实际上是Grouping
    • 是的;这只是一个嵌套类。请注意,它从外部类继承其泛型类型参数。
    猜你喜欢
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2021-06-11
    相关资源
    最近更新 更多