Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以Func为键的字典_C#_Dictionary_Func - Fatal编程技术网

C# 以Func为键的字典

C# 以Func为键的字典,c#,dictionary,func,C#,Dictionary,Func,我想知道这是否是一个明智的选择为字典的关键?我想做的是使用表达式作为字典中的键,类似于: 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 =>

我想知道这是否是一个明智的选择为字典的关键?我想做的是使用表达式作为字典中的键,类似于:

    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
var map3=newdictionary();
map3.Add((x)=>x%2==0,1);
map3.Add((x)=>x%10==0,2);
// ...
var key=map3.Keys.SingleOrDefault(f=>f(2));
//键=(x)=>x%2
//map3[键]=1
这是一种比使用大if-else或switch语句更干净的方法

这有意义吗?行吗?有更简单的方法吗?

不,每当使用lambda时,C#构造一个新的委托实例,这样您就不能将它用作一致的密钥。例如:

        Func<int, int> f = x => x*x + 1;
        Func<int, int> g = x => x*x + 1;
        Console.WriteLine(f.Equals(g)); // prints False
Func f=x=>x*x+1;
Func g=x=>x*x+1;
Console.WriteLine(f.Equals(g));//打印错误
这将使字典键的使用变得笨拙,除非您有其他方法始终获取相同的实例

编辑:


Eric Lippert的回答表明编译器可以检测lambda是否相同(尽管它通常不会)。无论哪种方式,lambda/委托对键的选择都很糟糕。

考虑到您使用映射的方式,最好使用
列表,因为检查lambda的顺序将不再像在基于哈希的字典中那样是任意的。此方法还允许您跳过查找步骤:

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;
}
var map3=新列表{
新元组((x)=>x%2==0,1)
,新元组((x)=>x%10==0,2)
};
var t=map3.SingleOrDefault(t=>t.Item1(2));
如果(t!=null){
var v=t.Item2;
}

用最新语法重写@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);
}
void Main()
{
var map3=新列表{
(键:(x)=>x*2==4,值:1),
(键:(x)=>x*10==100,值:2)
};
var result=map3.SingleOrDefault(x=>x.Key(10));
Console.WriteLine(result.Value);
}
计算为
列表中不存在的Func时
SingleOrDefault
返回键为null且值为0的元素


上面的
是为了可读性,可以删除它们,在这种情况下,
结果。Intem2
将在一个字中产生输出

;不。这通常是一个合适的值,但作为一个关键点,我会避免它…这会使我的头脑在维护它时变得更强大。。