Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我必须显式地提供泛型参数类型,而编译器应该推断类型?_C#_.net_Generics_Type Inference - Fatal编程技术网

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

C# 为什么我必须显式地提供泛型参数类型,而编译器应该推断类型?,c#,.net,generics,type-inference,C#,.net,Generics,Type Inference,为什么我必须显式地提供泛型参数类型,而编译器应该推断类型 public static T2 Cast<T1,T2>(this T1 arg) where T2 : class where T1 : class { return arg as T2; } publicstatict2cast(这个T1参数),其中T2:class,其中T1:class { 返回arg作为T2; } 示例用法: objOfTypeT2 = objOfTypeT1.Cast<TypeT1

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

public static T2 Cast<T1,T2>(this T1 arg) where T2 : class where T1 : class
{
    return arg as T2;
}
publicstatict2cast(这个T1参数),其中T2:class,其中T1:class
{
返回arg作为T2;
}
示例用法:

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

与我希望使用更智能的编译器相比:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT2>();
objOfTypeT2=objOfTypeT1.Cast();
或者我应该更聪明一些:-)


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

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


<>原理可能是简化了类型推理规则(已经很复杂了,因为它们也必须考虑重载规则)。< /P> < P>推断不考虑返回类型;但是,您可以尝试拆分泛型;例如,您可以编写代码以允许:

.Cast().To<Type2>()
.Cast().To())
通过拥有(未经测试;仅供参考)

publicstaticcasthelper Cast(这个T对象){
返回新的CastHelper(obj);
}
公共结构帮助器{
来自obj的私有只读TF;
公共CastHelper(tfromobj){this.obj=obj;}
公营部门{
//你的代码在这里
}
}

我用过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;
}

我猜到了,所以我对参数进行了重新排序,以便推断出的类型将是最后一个参数,但不可能。@Jani:顺序在这里并不重要。编译器可以为您推断所有类型参数,在这种情况下,您可以省略所有类型参数,或者至少不能推断一个类型参数。在后一种情况下,您总是必须显式地指定所有这些函数;然后你可以给类显式的参数,而推断的参数在函数上。用普通的方式强制转换有什么问题?为什么不做一个公共的静态T强制转换(这个对象值){返回值为T;}?@Rauhotz我有你提到的,只是好奇和寻找另一个重载使我可以将它用于值类型,因为我不能用泛型约束进行重载。@Jani,看一看示例-我不包括from类型;只是目的地类型。是的,我想这是目前唯一的解决方案。考虑制作<代码> T2<代码>返回值,但是重命名<代码>结果<代码>到C *丢弃标识符<代码> >代码>,例如:代码> T2结果= ObjfType 1.代码>。又好又简洁!
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);