10

これが辞書の正しいキーの選択であるかどうか疑問に思いますか?私がやりたいのは、次のような式を辞書のキーとして使用することです。

    var map3 = new Dictionary<Func<int, bool>, int>();
    map3.Add((x) => x % 2 == 0, 1);
    map3.Add((x) => x % 10 == 0, 2);
    // ...

    var key = map3.Keys.SingleOrDefault(f => f(2));
    // key = (x) => x % 2
    // map3[key] = 1

これであるという考えは、大きなif-elseまたはswitchステートメントを持つよりもクリーンな方法です。

これは意味がありますか?それは機能しますか?もっと簡単な方法はありますか?

4

3 に答える 3

9

マップの使用方法を考慮するとList<Tuple<Func<int,bool>,int>>、ハッシュベースの辞書のようにラムダをチェックする順序が任意ではなくなるため、を使用する方が適切です。このアプローチでは、ルックアップ手順をスキップすることもできます。

var map3 = new List<Tuple<Func<int,bool>,int>> {
    new Tuple<Func<int,bool>,int>((x) => x % 2 == 0, 1)
,   new Tuple<Func<int,bool>,int>((x) => x % 10 == 0, 2)
};
var t = map3.SingleOrDefault(t => t.Item1(2));
if (t != null) {
    var v = t.Item2;
}
于 2012-11-16T02:28:15.120 に答える
8

いいえ、C#はラムダが使用されるたびに新しいデリゲートインスタンスを構築するため、一貫性のあるキーとして使用することはできません。例:

        Func<int, int> f = x => x*x + 1;
        Func<int, int> g = x => x*x + 1;
        Console.WriteLine(f.Equals(g)); // prints False

これにより、常に同じインスタンスを取得する他の方法がない限り、辞書キーとしての使用が厄介になります。

編集:

ここでのEricLippertの回答は、コンパイラがラムダが同じであることを検出できることを示しています(ただし、通常は検出されません)。いずれにせよ、ラムダ/デリゲートはキーの選択に適していません。

于 2012-11-16T02:27:13.713 に答える
1

@dasblinkenlightの回答を最新の構文で書き直します。

void Main()
{
    var map3 = new List<(Func<int, bool> Key, int Value)> {
        (Key: (x) => x * 2 == 4, Value: 1),
        (Key: (x) => x * 10 == 100, Value: 2)
    };

    var result = map3.SingleOrDefault(x => x.Key(10));
    Console.WriteLine(result.Value);
}

Key存在しないFuncに評価されると、List SingleOrDefaultキーがnullで値が0の要素が返されます。

Key上記は読みやすさのためのものでありValue、削除することができ、その場合result.Intem2は出力が生成されます

于 2019-08-22T04:12:15.530 に答える