Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2 methods using 2 generics of same type

Tags:

c#

generics

If I have a class as below:

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

  public void DoSomething(U u)
  {
  }
}

But construct it using the same types (new MyClass<int,int>()) This compiles fine, but if I try to call DoSomething it errors because of an ambiguous call, which of course is correct. But what if the method was called through reflection or some other dynamic way. I guess it would throw an exception at run time. So my question is why does the compiler allow me create this class with the same types if there's an exception waiting to happen?

like image 786
RichK Avatar asked Jul 23 '10 10:07

RichK


People also ask

Can we define more than one generic datatype in a class?

You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.

Can a generic class have multiple generic parameters?

A Generic class can have muliple type parameters.

Can a method that uses a generic class parameter be static?

Static and non-static generic methods are allowed, as well as generic class constructors. The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method's return type.

In which way generic declares one or more type variables?

An interface is generic if it declares one or more type variables. These type variables are known as the type parameters of the interface. It defines one or more type variables that act as parameters. A generic interface declaration defines a set of types, one for each possible invocation of the type parameter section.


2 Answers

The compiler is concerned with actual ambiguity and does not highlight any ambiguity related to overloading generic methods.

If you don't want to allow this, unfortunately there's no way to add a Generic Type Constraint, i.e. where T != U, so you'll need to just throw an exception in the constructor:

public MyClass()
{
    if (typeof(T) == typeof(U))
    {
       throw new Exception("T and U cannot be of the same type");
    }
}

What you should do is use different names so that the two method names to not collide with one another. This is the safest way of working in this scenario:

public DoSomethingWithFirst()
{
   // For T
}

public DoSomethingWithSecond()
{
   // For U
}
like image 86
djdd87 Avatar answered Oct 14 '22 22:10

djdd87


Well, does it make sense to be able to have T and U be the same type, if you don't want to call DoSomething? If so, wouldn't it be infuriating to be prevented by the compiler for no reason?

In fact, the method could be called with reflection, if you picked the method carefully.

I would say that if the compiler should do anything, it should be warning the author of this class itself (not the user of the class) that the overload could lead to ambiguity in some cases. Frankly overload can cause plenty of problems - anything nudging people away from it in dangerous situations would be a good thing :)

like image 1
Jon Skeet Avatar answered Oct 14 '22 22:10

Jon Skeet