当返回类型为泛型接口时,如何将对象强制转换为泛型返回类型

本文关键字:返回类型 对象 泛型 转换 泛型接口 | 更新日期: 2023-09-27 18:28:42

我有一个非常丑陋的方法,它应该从数据库中提取各种数据,并使用它构造一个请求类型的对象。目标是将各种丑陋的东西放在一个地方,这样从包含此方法的类派生的类就可以相对干净。

当它应该返回单个对象时,即使类型可以为null,我也没有问题:

protected T getValue<T>(ParameterObject myParameterObject)
{
    var typeOfT = typeof (T);
    if (typeOfT == typeof(bool))
    {
        string val = this.getValue(myParameterObject);
        if (val == null)
            return default(T);
        bool rVal;
        if (!Boolean.TryParse(val, out rVal))
            return default(T);
        return changeType<T>(rVal);
    }
    if (typeOfT == typeof (double?))
    {
        string val = this.getValue(myParameterObject);
        if (val == null)
            return default(T);
        double rVal;
        if (!Double.TryParse(val, out rVal))
            return default(T);
        return changeType<T>(rVal);
    }
    [...]
}
public static T changeType<T>(object value)
{
    var t = typeof(T);
    if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Nullable<>))
        return (T)Convert.ChangeType(value, t);
    if (value == null)
        return default(T);
    t = Nullable.GetUnderlyingType(t);
    return (T)Convert.ChangeType(value, t);
}

不幸的是,在某些情况下,我想要的返回类型是IList,我想返回List:

protected T getValue<T>(ParameterObject myParameterObject)
{
    var typeOfT = typeof (T);
    if (typeOfT.IsGenericType)
    {
        if (typeOfT.GetGenericTypeDefinition() == typeof (IList<>))
        {
            var genericArgumentType = typeOfT.GenericTypeArguments.FirstOrDefault();
            var baseType = typeof (List<>);
            var genericType = baseType.MakeGenericType(new[] {genericArgumentType});
            var rVal = Activator.CreateInstance(genericType);
            [code to populate the list] 
            return changeType<T>(rVal);
        }
    [...]
}

我不能返回rVal,因为它是一个对象,而不是t的实例。但是我的changeType()函数失败了,出现了一个错误:

System.InvalidCastException:对象必须实现IConvertable。

所以,我有一个泛型方法,它的返回类型是IList,我有个对象是List,但我对它的引用是object类型。如何对其进行强制转换,以便从函数中返回它?

当返回类型为泛型接口时,如何将对象强制转换为泛型返回类型

由于value对象未实现IConvertiblereturn (T)Convert.ChangeType(value, t);行失败。

来自MSDN文档

[…]要使转换成功,value必须实现IConvertable接口,因为该方法只是封装对适当IConverable方法的调用。该方法要求支持将值转换为conversionType。

要解决此问题,我不确定通用方法,但对于valueIEnumerableIEnumerable<>类型的特定情况,可以尝试强制转换,然后执行value.Select(x => changeType<ListGenT>(x)) linq查询。通过递归地使用changeType方法,这也应该处理嵌套的泛型类型。