簡體   English   中英

在包括接口的類型之間切換

[英]Switch between types including interfaces

我為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)

為了實現這種方法,我嘗試使用字典( 受此答案啟發 )打開默認值的類型:

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)](); 在鍵集合(而不是IEnumerable<int>內尋找List<int> IEnumerable<int>

我正在努力避免反射(並將其保留為最后的手段)。 接口是否有類似於Type.IsAssignableFrom(Type)方法的方法? 換句話說,我想檢查提供的類型是否實現了IEnumerable<int>而不是它。

您無法以這種方式在字典中查找類型。 您必須遍歷鍵值對:

Type targetType = defaultValue.GetType();
foreach (var pair in dictionary)
{
    if (pair.Key.IsAssignableFrom(targetType))
    {
        // Use pair.Value
    }
}

但是,就您的使用方式而言,到目前為止,您實際上只是得到了List<Tuple<Type, Action>>而不是字典...因此,您可以使用:

List<Tuple<Type, Action>> actions = new List<Tuple<Type, Action>>
{
    Tuple.Create(typeof(bool), () => dob.GetPropertyValue(propId, (bool) (object)defaultValue),
    Tuple.Create(typeof(int), () => dob.GetPropertyValue(propId, (int) (object)defaultValue),
    // etc
};

...,然后在之前的循環中使用Item1Item2

您可以使用as運算子

var isEnumerable = defaultValue as IEnumerable;
if (isEnumerable != null)
{

}

暫無
暫無

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

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