簡體   English   中英

如何使用集合來存儲委托?

[英]How do I use a collection to store a delegate?

我希望有一個哈希表,其中字符串為鍵,而functionpointer(委托)為值。 這樣在給定基於字符串的命令的情況下調用正確的例程 但是,編譯器不會吃它。

我究竟做錯了什么?

//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':無法從'方法組'轉換為'對象'

我希望它只是一些語義上的東西我忘記了......但如果不能這樣做......還有另一種方法來獲得某種基於字符串的跳轉表嗎?

問題是你使用的是弱類型的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);
 }

如果您使用.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");

不要使用哈希表使用Dictionary

你的代碼也會改變。

//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)
     {
          ...
     }

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

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

順便說一句,如果您使用的是.NET 2.0或更高版本,則應使用通用Dictionary<T,T>類而不是Hashtable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM