4

そのため、メソッドに渡されたランダムなIEnumerableがグループ化されているかどうかを調べようとしています。グループ化されたデータを別の方法で処理するという考え方です。私の問題は、IGrouping<>非ジェネリックインターフェイスを実装していないジェネリックインターフェイスであり、何らかの理由でisステートメントでテストできないことです。

これをテストするために、ここに私のサンプルコードがあります:

        var dict = new Dictionary<int, string>() {
            {1, "Prime" },
            {2, "Prime" },
            {3, "Prime" },
            {4, "Not" },
            {5, "Prime" },
            {6, "Not" },
            {7, "Prime" },
            {8, "Not" },
            {9, "Not" },
            {10, "Not" },
            {11, "Prime" }
        };
        var grouped = from d in dict
                      group d by d.Value into gd
                      select gd;
        Debug.WriteLine("IEnumerable<IGrouping<string, KeyValuePair<int, string>>>: {0}", grouped is IEnumerable<IGrouping<string, KeyValuePair<int, string>>>);
        Debug.WriteLine("IEnumerable<IGrouping<object, KeyValuePair<int, string>>>: {0}", grouped is IEnumerable<IGrouping<object, KeyValuePair<int, string>>>);
        Debug.WriteLine("IEnumerable<IGrouping<object, KeyValuePair<object, object>>: {0}", grouped is IEnumerable<IGrouping<object, object>>);
        Debug.WriteLine("IEnumerable<IGrouping<object, object>: {0}", grouped is IEnumerable<IGrouping<object, object>>);
        Debug.WriteLine("IEnumerable<object>: {0}", grouped is IEnumerable<object>);

出力は次のとおりです。

IEnumerable<IGrouping<string, KeyValuePair<int, string>>>: True
IEnumerable<IGrouping<object, KeyValuePair<int, string>>>: True
IEnumerable<IGrouping<object, KeyValuePair<object, object>>: False
IEnumerable<IGrouping<object, object>: False
IEnumerable<object>: True

したがって、グループ化されている値のタイプを知らない限り、グループ化されているかどうかをテストすることはできないようです。これは.NetFrameworkのバグですか?

上記の結果はどのように可能ですか?


編集:ジョンスキートの答えは死んでいた...私が持っていたのと同じ困難でここにいる他の人への礼儀として、次のコードはIEnumerableがグループ化されているかどうかを確認する仕事をしました(Mrに基づいて.dynamicキーワードを使用するというSkeetの派手なアイデア):

    public static bool IsGrouped (dynamic test) {
        return CheckGrouping(test);
    }
    static bool CheckGrouping(object o ) {
        return false;
    }
    static bool CheckGrouping<TKey, TValue>(IEnumerable<IGrouping<TKey, TValue>> grouping) {
        return true;
    }

コードが上記と同じであると仮定します。

IsGrouped(dict); //false
IsGrouped(grouped); //true
4

1 に答える 1

10

結果は可能であるだけでなく、 .NET4で期待されます。.NET3.5では、一般的な差異がないため、最終的な結果はFalseになります。

はとIGrouping<out TKey, out TValue>の両方で共変ですTKeyTValueKeyValuePair<Tkey, TValue>は構造体であるため、共変の方法で使用することはできません。

つまり、anIGrouping<string, string>はですが、IGrouping<object, object>そうでIGrouping<string, KeyValuePair<int, string>>はありません。

これはフレームワークのバグではありません。IGrouping<TKey, TValue>何かがいくつかのペアに実装されているかどうかを確認する方法についてはTKey, TValue、自分でかなり一生懸命働くか、またはを使用dynamicして支援を試みることができます。

// Code as before...
dynamic dyn = grouped;
ShowGrouping(dyn);

private static void ShowGrouping<TKey, TValue>
   (IEnumerable<IGrouping<TKey, TValue>> grouping)
{
    Console.WriteLine("TKey = {0}, TValue = {1}", typeof(TKey), typeof(TValue));
}

private static void ShowGrouping(object notGrouped)
{
    Console.WriteLine("Not a grouping");
}

これは確かに絶対確実ではないことに注意してください-しかし、それはあなたが必要とするものには十分かもしれません。

于 2012-02-02T20:47:12.710 に答える