为什么我必须提供显式泛型参数类型而编译器应该推断出类型?

时间:2010-12-18 10:19:42

标签: c# .net generics type-inference

为什么我必须提供明确的通用参数类型,而编译器应该推断类型?

public static T2 Cast<T1,T2>(this T1 arg) where T2 : class where T1 : class
{
    return arg as T2;
}

样本用法:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT1,TypeT2>();


与我对智能编译器的期望用法相比:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT2>();

或者我应该更聪明: - )

请注意我提供了返回类型。我想不提供我在其上调用函数的对象,该方法是扩展方法

3 个答案:

答案 0 :(得分:18)

推理不考虑返回类型;但是,你可以尝试拆分泛型;例如,您可以编写代码以允许:

.Cast().To<Type2>()

通过(未经测试;仅供参考)

public static CastHelper<T> Cast<T>(this T obj) {
    return new CastHelper<T>(obj);
}
public struct CastHelper<TFrom> {
    private readonly TFrom obj;
    public CastHelper(TFrom obj) { this.obj = obj;}
    public TTo To<TTo>() {
       // your code here
    }
}

答案 1 :(得分:13)

规范将泛型方法的类型参数推断限制为全部或全部。你无法进​​行部分推断。

基本原理可能是简化类型推断规则(已经相当复杂,因为它们也必须考虑重载规则)。

答案 2 :(得分:2)

我已经使用了马克·格雷夫(Marc Gravell)的解决方案,并且喜欢它,但是我可以提出另一种选择。

由于可以从参数中推断出通用参数,因此另一种选择是对结果使用out参数而不是返回值。

这已经有很长时间了,但是今天的C#允许您声明内联变量,我发现这是可用的流程。

public static void Cast<T1, T2>(this T1 arg, out T2 result) where T2 : class where T1 : class
{
    result = arg as T2;
}

您可以这样称呼

objOfTypeT1.Cast(out Type2 objOfTypeT2);