2016-12-28 82 views
1

我有一本字典 - 其中的關鍵是System.Type。我不會進一步限制字典條目;但是,字典只能通過公共類接口公開。我模仿一個事件系統。約束System.Type作爲類型安全的通用參數

System.Collections.GenericDictionary模樣:

private Dictionary<Type, HashSet<Func<T>>> _eventResponseMap; 

一個暴露詞典具有以下簽名的方法:

public bool RegisterEventResponse<T>(Type eventType, Func<T> function) 

不過,我不希望類用戶能夠通過此簽名將任何System.Type添加到字典中。有沒有辦法可以進一步限制Type參數?

我真正想要的是一個類似於(僞代碼):

public bool RegisterEventResponse<T>(Type eventType, Func<T> function) where Type : ICustomEventType 
+0

上面的代碼中可能存在一些垃圾。如果你可以看看它,那會很棒。我在黑暗中拍攝,概念上(將根據建議更改) – Thomas

+1

而不是'Type',您可以使用另一種通用類型,如'T2',並將其限制爲您想要的特定類型。 [這已經在這裏回答](http://stackoverflow.com/a/4834066/4767498)使用策略模式。如果沒有使用正確的類型,這種方法會給你編譯時錯誤。更簡單的方法是在運行時檢查類型。 –

回答

2

爲什麼不改變你的方法的簽名?

public bool RegisterEventResponse<TEvent, TReturn>(Func<TReturn> function) 
    where TEvent: ICustomEventType 
{ 
    _eventResponseMap[typeof(TEvent)] = function; 
} 

是的,你失去了類型推斷,但你獲得類型安全。而不是寫RegisterEventResponse(typeof(CustomEvent),() => 1)你需要寫RegisterEventResponse<CustomEvent, int>(() => 1)

+0

這我喜歡。對此的調用大致如何(使用任何需要演示的垃圾類型)? – Thomas

+2

請注意,這是我的意思是添加一個參數:) – BradleyDotNET

+0

@BradleyDotNET你介意我接受這個(根據我的上述評論的答案)?這是看起來像我需要的一個非常明確的例子。在這裏學習很多。 – Thomas

3

不,你不會得到Type編譯時的安全性。

你可以限制T(或添加參數)ICustomEventType然後用typeofRegisterEventResponse得到你正在尋找Type對象。

或者只是拋出一個異常:

if (!typeof(ICustomEventType).IsAssignableFrom(typeof(T)) 
{ 
    throw new ArgumentException("Type is not supported"); 
} 
+0

甚至沒有想到在這種情況下拋出一個錯誤。如果編譯時的安全性是可以實現的(不知道這是否可行)。錯誤的一個問題是它意味着用戶需要更加貼近實現細節 - 這不是一個巨大的反對意見,但是..你知道。 – Thomas

+1

@Thomas只有獲得編譯時安全的方法是限制一個實際的泛型參數(不是'Type'),就像在我的中段中一樣。 – BradleyDotNET

+0

@Thomas或者如果你沒有很多不同的類型,你可以編寫不同的方法重載。這怎麼可能導致乾燥問題。 –