我有一套get
函數的重載。每個人都有不同的輸入類型,但基本上是相同的簽名模式(如下):在包括接口的類型之間切換
string GetPropertyValue(int propId, string defaultValue)
bool GetPropertyValue(int propId, bool defaultValue)
int GetPropertyValue(int propId, int defaultValue)
IEnumerable<string> GetPropertyValue(int propId, IEnumerable<string> defaultValues)
IEnumerable<bool> GetPropertyValue(int propId, IEnumerable<bool> defaultValues)
IEnumerable<int> GetPropertyValue(int propId, IEnumerable<int> defaultValues)
我上簡化了API爲單個通用方法的工作(如下):
T GetPropertyValue<T>(int propId , T defaultValue)
要實現這樣的方法,我試圖用一個字典(inspired by this answer)的類型來切換上的默認值:
var actionDico = new Dictionary<Type, System.Action>
{
/* since the type of `defaultValue` is `T`, I cannot use `(bool)defaultValue` for example
therefore casting to (object) before to escape Cast operator restriction.
Will not fail as the key of the dictionary is a matching type */
{typeof(bool),() => dob.GetPropertyValue(propId, (bool)(object)defaultValue)},
{typeof(int),() => dob.GetPropertyValue(propId, (int)(object)defaultValue)},
{typeof(string),() => dob.GetPropertyValue(propId, (string)(object)defaultValue)}
}
隨着混凝土的類型,以前的實現是完全沒有(至少在我的情況下)。通話將使用actionDico[typeof(T)]();
完成。
具有字典中,以下是罰款:
{typeof(IEnumerable<int>),() => dob.GetPropertyValue(propId, (IEnumerable<int>)(object)defaultValue)},
但呼叫通常使用它們實現IEnumerable<int>
(List<int>
等)的對象來完成。在這種情況下,呼叫actionDico[typeof(T)]();
正在尋找密鑰集合中的List<int>
,而不是IEnumerable<int>
。
我試圖避免反思(並將它作爲最後的手段)。有沒有類似於Type.IsAssignableFrom(Type)
接口的方法?換句話說,我想檢查提供的類型實現IEnumerable<int>
而不是它。
我不清楚你想要用字典做什麼*做什麼,或者你正在談論的「演員操作員限制」是什麼。請注意,您可以非常容易地使用'typeof(IEnumerable)' - List「List 」在哪裏? (僅列出*列表是爲了說明你爲什麼不想在例子中使用'typeof' - 無處)。 –
@JonSkeet:請看看編輯 –
它相當於'actionDico [defaultValue.GetType()]'。當然,你得到List <>而不是IEnumerable <>。所以字典沒有用,你必須枚舉類型來找到匹配。你當然堅持使用IsAssignableFrom(),它並不昂貴。 –