繁体   English   中英

从Dictionary泛型确定可空项目

[英]Determine nullable item from Dictionary generic

我有一本词典

Dictionary<string, object> dict = new Dictionary<string, object>() { { "foo", 2.5 } };

我必须通过通用方法确定值

public static Type GetRes<Type>(Dictionary<string, object> dict, string key)
{
    if (dict.ContainsKey(key) && dict[key].GetType() == typeof(Type))
    {
        return (Type)dict[key];
    }
    return default(Type);
}

该调用看起来如下

double? result1 = GetRes<double?>(dict, "foo"); // expected 2.5
double? result2 = GetRes<double?>(dict, "bar"); // expected null

遗憾的是,这不适用于dict[key].GetType() == typeof(Type)结果始终为false,因为typeof(double) == typeof(double?)始终为false。


我尝试过的:

// changed the call from double? to double
double? result1 = GetRes<double>(dict, "foo"); 
double? result2 = GetRes<double>(dict, "bar");

Methdod:

// chagned Type to Nullable<Type>
public static Nullable<Type> GetRes<Type>(Dictionary<string, object> dict, string key)
{
    if (dict.ContainsKey(key) && dict[key].GetType() == typeof(Type))
    {
        return (Nullable<Type>)dict[key];
    }
    return default(Nullable<Type>);
}

这不编译。

解决方案是添加where Type : struct ,如下所示:

public static Type? GetRes2<Type>(Dictionary<string, object> dict, string key) where Type : struct
{
    if (dict.ContainsKey(key) && dict[key].GetType() == typeof(Type))
    {
        return (Type?)dict[key];
    }
    return default(Type?);
}

“类型”类型必须non-nullable value type才能将其用作参数“T”。 然后你可以使用where Type : struct强制'Type'为value type

为什么不检查dict [key]是你的类型:

 public static Type GetRes<Type>(Dictionary<string, object> dict, string key)
        {
            if (dict.ContainsKey(key) && dict[key] is Type)
            {
                return (Type)dict[key];
            }
            return default(Type);
        }

以下扩展方法应该可以解决这个问题:

public static T GetValue<T>(this Dictionary<string, object> dictionary, string key)
{
    if (dictionary == null)
    {
        throw new ArgumentNullException(nameof(dictionary));
    }

    if (!dictionary.ContainsKey(key))
    {
        return default(T); //Or null, depending on you needs
    }

    var value = dictionary[key];

    if (value == null)
    {
        return default(T);
    }

    if (value is IConvertible)
    {
        return (T)Convert.ChangeType(value, typeof(T));
    }

    return (T)value;
}

你可以这样称呼它:

var dict = new Dictionary<string, object>() {
    { "foo1", 2.5 },
    { "foo2", "my string" },
    { "foo3", new MyClass() },
    { "foo4", 1 },
    { "foo5", null }
};

var res1 = dict.GetValue<float>("foo1");
var res2 = dict.GetValue<string>("foo2");
var res3 = dict.GetValue<MyClass>("foo3");
var res4 = dict.GetValue<int>("foo4");
var res5 = dict.GetValue<int?>("foo5");

为结构类型尝试此方法签名:

public static T? GetValue<T>(this Dictionary<string, object> dictionary, string key) where T : struct
{
    //implementation should be the same
}

您应该使用“is”来检查是否可以转换对象

public static Type GetRes<Type>(Dictionary<string, object> dict, string key)
{
   if (dict.ContainsKey(key) && dict[key] is Type)
   {
      return (dict[key] as Type);
   }
   return default(Type);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM