C# 使用相同类型的2个泛型的2个方法

C# 使用相同类型的2个泛型的2个方法,c#,generics,C#,Generics,如果我有以下课程: class MyClass<T,U> { public void DoSomething(T t) { } public void DoSomething(U u) { } } class-MyClass { 公共无效剂量测定(T) { } 公共无效剂量(U) { } } 但是使用相同的类型来构造它(newmyclass()) 这可以很好地编译,但是如果我尝试调用DoSomething它会因为调用不明确而出错,这当然是正确的。但是如果

如果我有以下课程:

class MyClass<T,U>
{
  public void DoSomething(T t)
  {
  }

  public void DoSomething(U u)
  {
  }
}
class-MyClass
{
公共无效剂量测定(T)
{
}
公共无效剂量(U)
{
}
}
但是使用相同的类型来构造它(
newmyclass()

这可以很好地编译,但是如果我尝试调用
DoSomething
它会因为调用不明确而出错,这当然是正确的。但是如果该方法是通过反射或其他动态方式调用的呢。我猜它会在运行时抛出一个异常。所以我的问题是,如果有异常等待发生,编译器为什么允许我创建具有相同类型的类?

如果不想调用
DoSomething
,那么让T和U成为相同类型有意义吗?如果是这样的话,编译器无缘无故地阻止它不是很恼火吗

事实上,如果仔细选择方法,可以使用反射调用该方法


我想说,如果编译器应该做任何事情,它应该警告这个类本身的作者(而不是该类的用户),过载在某些情况下可能导致歧义。坦率地说,过载会导致很多问题——在危险的情况下,任何能让人们远离它的东西都是一件好事:)

您希望编译器不允许这样做吗?有无限多的情况是好的,而这一个不是。

编译器关注实际的歧义,并且不突出任何与重载泛型方法相关的歧义

如果您不想允许这样做,很遗憾,没有办法添加泛型类型约束,即
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
}

顺便说一句,如果您不控制该类,并且希望允许在
MyClass
上调用这些方法,那么您可以在不进行反射的情况下执行该操作,并且在运行时将毫无例外地成功。例如,如果您创建了一个以
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);
    }
}
公共静态类MyClassExtensions
{
公共静态void DoSomethingT(此MyClass obj,T)
{
目标剂量测定法(t);
}
公共静态无效DoSomethingU(此MyClass obj,U)
{
目标剂量测定法(u);
}
}
DoSomethingT
将选择使用
T
DoSomething
重载。这是在编译时选择的,对
T
U
的所有值都有效。然后可以使用
MyClass
调用
mybj.DoSomethingT(3)
,它将调用
MyClass.DoSomething(T)


(正如其他人所说,如果你控制了这个类,那么你应该给这些方法起不同的名字。)

谢谢大家的回答。你们中的一些人已经说过,对方法进行不同的命名,这显然是最好的解决方案。顺便说一句,我最初注意到这个场景不是使用方法,而是使用索引(this[T]和this[U]),因此不可能重命名方法。我现在已经改变了设计,所以原来的问题无论如何都不存在,但这个问题可能仍然会引起某些人的兴趣:)