繁体   English   中英

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

[英]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>上调用这些方法,则可以无反射地进行操作,并且它将在运行时成功,没有例外。 例如,如果创建一个以TU作为参数的通用方法,则该方法中的重载分辨率可以将它们区分开:

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将选择需要TDoSomething重载。 这是在编译时选择的,并且对于TU所有值都有效。 然后,可以使用MyClass<int, int>调用myObj.DoSomethingT(3) ,它将毫无歧义地调用MyClass.DoSomething(T t)

(正如其他人所说的,如果您确实控制了类,则应该为方法指定不同的名称。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM