【问题标题】:Why must I provide explicitly generic parameter types While the compiler should infer the type?为什么我必须显式提供泛型参数类型而编译器应该推断类型?
【发布时间】:2010-12-18 10:19:41
【问题描述】:

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

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>();

或者我应该更聪明:-)

请注意,我提供了返回类型。我不想提供我在上面调用函数的对象,方法是Extension Method

【问题讨论】:

  • 正常投射有什么问题?
  • 为什么不直接创建一个公共静态 T Cast(this object value) { return value as T;}?
  • @Rauhotz 我有你提到的,只是好奇和寻找另一个重载使我能够将它与值类型一起使用,因为我无法使用泛型约束进行重载。

标签: c# .net generics type-inference


【解决方案1】:

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

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

【讨论】:

  • @Jani 并查看示例 - 我不包括 from 类型;只是目的地类型。
  • 是的,我想说这是目前唯一的解决方法。
【解决方案2】:

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

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

【讨论】:

  • 我猜到了,所以我对参数重新排序,以便推断的类型是最后一个参数,但没有机会。
  • @Jani:订单在这里并不重要。编译器可以为您推断出所有类型参数,在这种情况下您可以将它们全部省略,或者它不能推断出至少一个。在后一种情况下,您将始终必须明确指定 所有
  • 对于静态,您可以通过将函数放在具有通用参数的虚拟工具集类中来解决此问题;那么你可以给类提供显式参数,而推断的参数在函数上。
【解决方案3】:

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

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

这已经可能很久了,但是今天的 C# 允许您将变量声明为 inline,我发现这是一个可用的流程。

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);

【讨论】:

  • 考虑将T2 设为返回值,但将result 重命名为C# 丢弃标识符_,例如T2 result = objOfType1.Cast(out Type2 _);。简洁明了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2011-04-27
  • 1970-01-01
相关资源
最近更新 更多