use*_*689 10 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 => f(2));
// key = (x) => x % 2
// map3[key] = 1
Run Code Online (Sandbox Code Playgroud)
这样做的想法比拥有大的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
Run Code Online (Sandbox Code Playgroud)
这将使得使用尴尬作为字典键,除非您有其他方式来始终获得相同的实例.
编辑:
Eric Lippert 在这里的答案表明允许编译器检测lambda是相同的(虽然它通常不会).无论哪种方式,lambda/delegate都是键的糟糕选择.
考虑到你使用地图的方式,你最好使用a List<Tuple<Func<int,bool>,int>>,因为检查lambdas的顺序将不再是任意的,就像在基于散列的字典中一样.此方法还允许您跳过查找步骤:
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;
}
Run Code Online (Sandbox Code Playgroud)