2009-12-04 127 views
5

有沒有人聽說過使用類型作爲鍵並支持繼承的「類型字典」?類型字典?

在我的申請,我想有從類型功能的字典,有點像這樣:

Dictionary<Type, Func<object, object>> Transformers; 

的想法是,它會根據使用以某種方式變換對象,其鍵入:

// Transform an object 'obj' 
object result = Transformers[obj.GetType()](obj) 

普通字典的缺點是類型必須完全匹配。因此,如果我已經爲IList < T>寫了一個變壓器,將它放入變形金剛字典中是沒有用的,因爲沒有物體具有IList < T>(僅T [],列表< T>等)。換句話說,如果obj是列表< T>,則IList < T>的變換器將不會通過普通字典中的查找找到。

假設有一個TypeDictionary < TValue>中沒有這樣的事情,我可能會考慮寫一個,如果它不是太難。任何想法如何實現?

回答

2

您應該可以使用帶有custom comparer的字典,它使用Type.IsAssignableFrom來比較密鑰。

更新:正如Qwertie指出的,這不起作用,因爲您無法實現基於類型,其接口和祖先類的可重複哈希碼計算。 His answer通過反覆對類型,接口和祖先類進行哈希表查找,直到找到匹配項爲止,提供了一種可能的解決方案。

與解決方案的唯一問題是你沒有任何辦法來指定哪些匹配時有多個匹配服用。如果您需要這種靈活性和控制力,我建​​議您考慮chain-of-responsibility設計模式。每個變壓器可能是鏈條中的一個環節,它負責確定它是否可以應用於物體。如果不是,它會將請求傳遞到下一個鏈接。鏈中變壓器的順序決定了優先級。你失去了哈希表的速度,但是由於多次查找,你無論如何都失去了一些速度。

+1

這是行不通的。 IEqualityComparer對於從A派生並實現IA和IB的類B返回哪個哈希碼?另外,請記住詞典應該能夠同時保存'List ','IList '和'object'的鍵。 – Qwertie 2009-12-04 18:20:29

+0

你說得對,我沒有想到通過。 – 2009-12-04 18:56:08

+0

@Qwertie在這種情況下,如果字典中有幾個匹配類型的話,你的字典會返回什麼?它是否應該返回所有的事件,只有最專業的等等? – 2009-12-04 19:04:17

1

的字典二傳手沒有不同的語義從一個普通的字典,所以一個方法是使用一個標準的字典,專門查找它發生對我說:

public class TypeDictionary<TValue> : Dictionary<Type, TValue> 
{ 
    public new TValue this[Type key] 
    { 
     get { 
      TValue value; 
      if (TryGetValue(key, out value)) 
       return value; 
      throw new KeyNotFoundException("Not found: " + key.Name); 
     } 
    } 
    public new bool TryGetValue(Type key, out TValue value) 
    { 
     if (base.TryGetValue(key, out value)) 
      return true; 

     Type[] interfaces = key.GetInterfaces(); 
     for (int i = 0; i < interfaces.Length; i++) 
      if (base.TryGetValue(interfaces[i], out value)) 
       return true; 

     Type @base = key.BaseType; 
     if (@base != null && TryGetValue(@base, out value)) 
      return true; 

     return false; 
    } 
} 

注意,如果B類導出來自類A和接口IA和IB,並且爲每個類型分配一個值,這是不明確的:應該返回A,IA還是IB的值?上面的實現選擇它找到的第一個接口,並且只有在沒有找到接口的情況下,纔會查找基類。

我不知道這本詞典的表現有多好。如果GetInterfaces()或BaseType屬性很慢,它會使查找性能非常糟糕(只要您請求的確切類型不在字典中)。

相關問題