如何使用集合来存储委托?

时间:2009-09-17 13:58:48

标签: c# delegates

我希望哈希表有一个字符串作为键,而一个函数指针(委托)作为值。 这样在给定基于字符串的命令的情况下调用正确的例程 但是,编译器不会吃它。

我做错了什么?

//declaration
     public delegate void categoryHandler(String request);     

//init code
     Hashtable categories = new Hashtable();
     categories.Add("campaigns", Campaigns.post);

//function call
     String category = "campaigns";
     categoryHandler handler = (categoryHandler) categories[category];
     if (handler != null)
     {
          handler(someString);
     }

//handler
     static public void post(String request)
     {
          ...
     }

我得到的错误是我将函数放在哈希表中的行: 错误2参数'2':无法从'方法组'转换为'对象'

我希望这只是一些语义上的东西,我忘了...... 但如果不能做到这一点......还有另一种方法可以获得某种基于字符串的跳转表吗?

4 个答案:

答案 0 :(得分:8)

问题是您使用的是弱类型的Hashtable。编译器会看到方法组(要转换为委托的方法的名称),但不知道您的委托类型。

如果你想继续使用Hashtable,你可以这样做:

categoryHandler handler = Campaigns.post;
categories.Add("campaigns", handler);

categories.Add("campaigns", new categoryHandler(Campaigns.post));

在这两种情况下,方法组都被转换为特定的委托类型,所以没关系。

然而,更好的解决方案是首先使用Dictionary<string, categoryHandler> - 始终使用强类型集合,您可以明智地这样做(这几乎总是如此)。为了惯例,它应该是CategoryHandler btw - 它是一个类型的名称。同样,post应为Post

然后调用它,你会使用:

 String category = "campaigns";
 CategoryHandler handler;
 if (categories.TryGetValue(category, out handler))
 {
     handler(someString);
 }

答案 1 :(得分:2)

如果您使用的是.Net 3.5,那么当我想要删除switch语句时,您可以执行我的操作:

private readonly Dictionary<string, Action<string>> _lookupTable = new Dictionary<string, Action<string>>
{
    {"campaigns", post}
    {"somethingElse", doSomethingElse}
    {"tryIt", val => doSomethingWithVal(val)} 
};

然后,我会有一个switch语句,我会这样做:

_lookupTable["foo"]("bar");

答案 2 :(得分:1)

不要使用哈希表使用词典

您的代码也会改变。

//declaration
     public delegate void categoryHandler(String request);     

//init code
     Dictionary<string, categoryHandler> categories = new Dictionary<string, categoryHandler> ;
     categories.Add("campaigns", Campaigns.post);

//function call
     string category = "campaigns";

     if (!categories.ContainsKey(category))
     {
        // Key not there just return
        return;
     }

     categoryHandler handler = categories[category];  // NO need to cast here

     if (handler != null)
     {
          handler(someString);
     }

//handler
     static public void post(String request)
     {
          ...
     }

答案 3 :(得分:0)

根据您使用的C#版本,您可能需要执行以下操作:

categories.Add("campaigns", new categoryHandler(Campaigns.post));

顺便说一句,如果您使用的是.NET 2.0或更高版本,则应该使用通用Dictionary<T,T>类而不是Hashtable