[英]2 methods using 2 generics of same type
如果我的课程如下:
class MyClass<T,U>
{
public void DoSomething(T t)
{
}
public void DoSomething(U u)
{
}
}
但是使用相同的类型( new MyClass<int,int>()
)构造它可以很好地编译,但是如果我尝试调用DoSomething
则由于调用不明确而导致错误,这当然是正确的。 但是,如果该方法是通过反射或其他动态方式调用的,该怎么办? 我猜想它将在运行时引发异常。 所以我的问题是,如果有等待发生的异常,为什么编译器允许我使用相同的类型创建此类?
编译器关心的是实际的歧义,没有强调与重载泛型方法有关的歧义。
如果您不希望这样做,那么很遗憾,无法添加通用类型约束,即where T != U
,因此您只需要在构造函数中抛出一个异常即可:
public MyClass()
{
if (typeof(T) == typeof(U))
{
throw new Exception("T and U cannot be of the same type");
}
}
您应该做的是使用不同的名称,以免两个方法的名称彼此冲突。 在这种情况下,这是最安全的工作方式:
public DoSomethingWithFirst()
{
// For T
}
public DoSomethingWithSecond()
{
// For U
}
好吧,如果您不想调用DoSomething
,那么使T和U具有相同的类型是否有意义? 如果是这样,编译器无缘无故阻止它会令人生气吗?
实际上,如果您仔细选择该方法,则可以通过反射调用该方法。
我要说的是,如果编译器应该执行任何操作,则应该警告此类本身的作者(而不是此类的用户 ),在某些情况下,重载可能导致歧义。 坦白说,过载可能会引起很多问题-在危险情况下让人们远离它的任何事情都是一件好事:)
你愿意编译器并没有允许这样做? 有无数个很好的案例,而这不是一个案例。
顺便说一句,如果您不控制该类,并且希望允许在MyClass<int, int>
上调用这些方法,则可以无反射地进行操作,并且它将在运行时成功,没有例外。 例如,如果创建一个以T
和U
作为参数的通用方法,则该方法中的重载分辨率可以将它们区分开:
public static class MyClassExtensions
{
public static void DoSomethingT<T, U>(this MyClass<T, U> obj, T t)
{
obj.DoSomething(t);
}
public static void DoSomethingU<T, U>(this MyClass<T, U> obj, U u)
{
obj.DoSomething(u);
}
}
DoSomethingT
将选择需要T
的DoSomething
重载。 这是在编译时选择的,并且对于T
或U
所有值都有效。 然后,可以使用MyClass<int, int>
调用myObj.DoSomethingT(3)
,它将毫无歧义地调用MyClass.DoSomething(T t)
。
(正如其他人所说的,如果您确实控制了类,则应该为方法指定不同的名称。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.