泛型方法的返回类型

11

我有一个通用的方法,它返回一个通用类型的对象。以下是一些代码:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return value;

    if (typeof(T) == typeof(int))
        return Int32.Parse(value);

    // Do more stuff
}

我可以看到编译器可能会抱怨这个问题("无法将类型 'String' 转换为 'T'"),即使代码在运行时不应该引起任何逻辑错误。有没有办法实现我想要的效果?强制转换也没有帮助...

1个回答

19

好的,你可以这样做:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return (T) (object) value;

    if (typeof(T) == typeof(int))
        return (T) (object) Int32.Parse(value);

    ...
}

这将涉及到对于值类型进行打包,但它会起作用。

您确定这样做是最好的方式吗?而不是(比如)一个能被不同转换器实现的通用接口?

或者,您可能需要一个像这样的Dictionary<Type, Delegate>

Dictionary<Type, Delegate> converters = new Dictionary<Type, Delegate>
{
    { typeof(string), new Func<string, string>(x => x) }
    { typeof(int), new Func<string, int>(x => int.Parse(x)) },
}

接下来,您可以像这样使用它:

public static T Foo<T>(string value)
{
    Delegate converter;
    if (converters.TryGetValue(typeof(T), out converter))
    {
        // We know the delegate will really be of the right type
        var strongConverter = (Func<string, T>) converter;
        return strongConverter(value);
    }
    // Oops... no such converter. Throw exception or whatever
}

我不得不对String类型也执行return (T)(object)value;,但这样可以正常工作。谢谢! :-) - Christian Rygg
@Chris:对我来说,字典方法感觉更加简洁...并且可以避免值类型的装箱。 - Jon Skeet
@Jon:这里的read方法比我在这里写的要复杂一些——我只是强调了我遇到的问题。所以你提出的替代方案并不相关,但我同意——这将是一种更清晰的方法来处理这种类型的方法。 - Christian Rygg
@Jon:刚刚注意到你在字符串的返回语句中添加了(string)。这是不起作用的-似乎必须是(object),供参考。 - Christian Rygg
我做了一个小基准测试...我认为编译器忽略了(T)(object)转换(如果我调用“泛型”函数或者我调用一个更直接调用Int32.Parse的函数,时间是相同的)。 - xanatos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接