为什么 Roslyn 不会为方法统一抛出错误?
Why does Roslyn not throw an error for method unification?
如果您尝试实现两个可能 "unify" 一组特定类型参数的接口,Roslyn 将抛出错误:
public interface IFoo<T1, T2>
{
void Method(T1 a, T2 b);
}
public class Foo<T1, T2> : IFoo<T1, T2>, IFoo<T2, T1>
{
public void Method(T2 a, T1 b) { }
public void Method(T1 a, T2 b) { }
}
Foo class 不会编译并且 Roslyn 会给你一个错误说“Foo<T1, T2>
不能同时实现 IFoo<T1, T2>
和 IFoo<T2, T1>
因为它们可能会统一某些类型参数替换。”即使对于大多数类型替换都没有问题,Roslyn 甚至不允许您声明这个 class 因为有人可能使用类型替换,其中 T1 == T2.
但是,编译器可以让你这样声明:
public class Bar<T1, T2>
{
public void Method(T1 t) { }
public void Method(T2 t) { }
}
此 class 编译正常,只有在客户端尝试调用该方法时才会抛出错误:
var bar = new Bar<int, int>();
bar.Method(5);
这里Roslyn报错说"This call is ambiguous between the following methods or properties: Bar<T1, T2>.Method(T1)
and Bar<T1, T2>.Method(T2)
."
我想知道为什么在这两种非常相似的情况下编译器的行为如此不同。编译器是否应该在您声明两个可能统一的方法时立即抛出错误?
可以调用每个单独的Bar.Method
方法:
public class Bar<T1, T2> {
public void Method(T1 t) {
Console.WriteLine("FirstMethod");
}
public void Method(T2 t) {
Console.WriteLine("SecondMethod");
}
}
public static void CallFirstMethod<T1, T2>(Bar<T1, T2> bar, T1 t) {
bar.Method(t);
}
public static void CallSecondMethod<T1, T2>(Bar<T1, T2> bar, T2 t) {
bar.Method(t);
}
public static void Test() {
var bar = new Bar<int, int>();
CallFirstMethod(bar, 5);
CallSecondMethod(bar, 6);
}
因此,在这种情况下没有理由产生错误。
如果您尝试实现两个可能 "unify" 一组特定类型参数的接口,Roslyn 将抛出错误:
public interface IFoo<T1, T2>
{
void Method(T1 a, T2 b);
}
public class Foo<T1, T2> : IFoo<T1, T2>, IFoo<T2, T1>
{
public void Method(T2 a, T1 b) { }
public void Method(T1 a, T2 b) { }
}
Foo class 不会编译并且 Roslyn 会给你一个错误说“Foo<T1, T2>
不能同时实现 IFoo<T1, T2>
和 IFoo<T2, T1>
因为它们可能会统一某些类型参数替换。”即使对于大多数类型替换都没有问题,Roslyn 甚至不允许您声明这个 class 因为有人可能使用类型替换,其中 T1 == T2.
但是,编译器可以让你这样声明:
public class Bar<T1, T2>
{
public void Method(T1 t) { }
public void Method(T2 t) { }
}
此 class 编译正常,只有在客户端尝试调用该方法时才会抛出错误:
var bar = new Bar<int, int>();
bar.Method(5);
这里Roslyn报错说"This call is ambiguous between the following methods or properties: Bar<T1, T2>.Method(T1)
and Bar<T1, T2>.Method(T2)
."
我想知道为什么在这两种非常相似的情况下编译器的行为如此不同。编译器是否应该在您声明两个可能统一的方法时立即抛出错误?
可以调用每个单独的Bar.Method
方法:
public class Bar<T1, T2> {
public void Method(T1 t) {
Console.WriteLine("FirstMethod");
}
public void Method(T2 t) {
Console.WriteLine("SecondMethod");
}
}
public static void CallFirstMethod<T1, T2>(Bar<T1, T2> bar, T1 t) {
bar.Method(t);
}
public static void CallSecondMethod<T1, T2>(Bar<T1, T2> bar, T2 t) {
bar.Method(t);
}
public static void Test() {
var bar = new Bar<int, int>();
CallFirstMethod(bar, 5);
CallSecondMethod(bar, 6);
}
因此,在这种情况下没有理由产生错误。