c# – 当返回类型是通用接口时,如何将对象强制转换为泛型返回类型?

我有一个非常丑陋的方法,它应该从数据库中提取各种数据,并使用它构造一个请求类型的对象.目标是将各种丑陋归结到一个地方,以便从包含此方法的类派生的类可以相对干净.

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

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: Object must implement IConvertible.

所以,我有一个泛型方法,返回类型是IList,我有一个List的对象,但我对它的引用是Object类型.如何投射它以便我可以从函数返回它?

最佳答案
你的返回(T)Convert.ChangeType(value,t); line失败,因为您的value对象没有实现IConvertible.

MSDN docs

[…] For the conversion to succeed, value must implement the 07001 interface, because the method simply wraps a call to an appropriate 07001 method. The method requires that conversion of value to conversionType be supported.

为了解决这个问题,我不确定一般的方法,但是对于IEnumerable或IEnumerable<>的值的具体情况.类型,然后你可以尝试强制转换然后执行一个值.选择(x => changeType< ListGenT>(x))linq查询.通过递归使用您的changeType方法,这也应该处理嵌套的泛型类型.

转载注明原文:c# – 当返回类型是通用接口时,如何将对象强制转换为泛型返回类型? - 代码日志