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

时间:2022-09-10 23:56:46

Why must I provide explicitly generic parameter types While the compiler should infer the type?

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

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

Sample Usage:

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


Compared to my desired usage with a more intelligent compiler:

与使用更智能的编译器的我想要的用法相比:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT2>();

or maybe I should be more intelligent :-)

或者我应该更聪明:-)

Beware that I provide the return type. I want to not provide the object that I called the function on it, the method is an Extension Method.

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

3 个解决方案

#1


13  

The specification limits type parameter inference for generic methods to all or nothing. You can't have partial inference.

规范将泛型方法的类型参数推断限制为全部或全部。你不能有部分推断。

The rationale is probably simplifying type inference rules (that are already pretty complex, as they have to take into account overloading rules too).

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

#2


16  

Inference doesn't consider the return type; you can, however, try splitting the generics; for example, you could write code to allow:

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

.Cast().To<Type2>()

by having (untested; indicative only)

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

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
    }
}

#3


0  

I've used Marc Gravell's solution and like it, but I can present another alternative.

我使用过Marc Gravell的解决方案并喜欢它,但我可以提出另一种选择。

Because the generic parameters are inferred from the parameters, another option is to use an out parameter for the result instead of a return value.

因为通用参数是从参数推断出来的,所以另一个选择是对结果使用out参数而不是返回值。

This have been possible for a long time, but today's C# allows you to declare the variable inline, which I find to be a usable flow.

这已经有很长一段时间了,但今天的C#允许你声明变量内联,我觉得这是一个可用的流程。

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

You can call this as follows

您可以按如下方式调用此方法

objOfTypeT1.Cast(out Type2 objOfTypeT2);

#1


13  

The specification limits type parameter inference for generic methods to all or nothing. You can't have partial inference.

规范将泛型方法的类型参数推断限制为全部或全部。你不能有部分推断。

The rationale is probably simplifying type inference rules (that are already pretty complex, as they have to take into account overloading rules too).

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

#2


16  

Inference doesn't consider the return type; you can, however, try splitting the generics; for example, you could write code to allow:

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

.Cast().To<Type2>()

by having (untested; indicative only)

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

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
    }
}

#3


0  

I've used Marc Gravell's solution and like it, but I can present another alternative.

我使用过Marc Gravell的解决方案并喜欢它,但我可以提出另一种选择。

Because the generic parameters are inferred from the parameters, another option is to use an out parameter for the result instead of a return value.

因为通用参数是从参数推断出来的,所以另一个选择是对结果使用out参数而不是返回值。

This have been possible for a long time, but today's C# allows you to declare the variable inline, which I find to be a usable flow.

这已经有很长一段时间了,但今天的C#允许你声明变量内联,我觉得这是一个可用的流程。

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

You can call this as follows

您可以按如下方式调用此方法

objOfTypeT1.Cast(out Type2 objOfTypeT2);