2012-11-16 140 views
8

我想知道这是否是一个字典的关键理智的选择?我想要做的是使用一个表达式作为字典的关键,是这样的: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 

的想法是,这是不是有大的if-else或switch语句一个更清洁的方式。

这是否有意义?它会起作用吗?有一种更简单的方法吗?

+1

总之,没有。这通常是一个合适的价值,但作为一个关键我会避免它。 – Servy

+2

..这将做我的头保持.. –

回答

7

不,C#在使用lambda时会构造一个新的委托实例,因此您无法将其用作一致性密钥。例如:

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

然后,这会使字符串的用法很尴尬,除非您有其他方法总是获取相同的实例。

编辑:

埃里克利珀的回答here表示该编译器是允许检测lambda表达式是相同的(尽管它通常不会)。无论哪种方式,lambda/delegate都不能为一个关键选择。

+0

好的谢谢,多数民众赞成在清除 – user380689

6

考虑到您使用地图的方式,您最好使用List<Tuple<Func<int,bool>,int>>,因为检查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; 
} 
+0

嗯,这是有趣的,我需要更多地研究它。谢谢。 – user380689