我希望哈希表有一个字符串作为键,而一个函数指针(委托)作为值。 这样在给定基于字符串的命令的情况下调用正确的例程 但是,编译器不会吃它。
我做错了什么?
//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':无法从'方法组'转换为'对象'
我希望这只是一些语义上的东西,我忘了...... 但如果不能做到这一点......还有另一种方法可以获得某种基于字符串的跳转表吗?
答案 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
。