Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method isn't choosing the most specific constructor signature?

Tags:

c#

generics

When I use a method with a generic parameter to create another object, the generic object isn't selecting the most specific constructor. That sounds confusing, so here's some sample code to demonstrate what I mean...

Can anyone explain why the output of this program is:

guid    <-- easy - no problem here
object  <-- WHY?  This should also be "guid"?!

...and how to make the generic Add<T> function call the correct constructor of C?? Here's the code:

void Main()
{
    B b = new B();

    C c = new C(Guid.Empty);
    b.Add<Guid>(Guid.Empty);
}

public class B
{
    List<C> cs = new List<C>();
    public void Add<T>(T v) { cs.Add(new C(v)); }
}

public class C
{
    public C(Guid c) { Console.WriteLine("guid"); }
    public C(object c) { Console.WriteLine("object"); }
}
like image 520
Michael Bray Avatar asked Jul 16 '13 18:07

Michael Bray


People also ask

Which of the following statements are true about generic methods in Java?

Explanation: Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.

How does a generic method differ from a generic type?

From the point of view of reflection, the difference between a generic type and an ordinary type is that a generic type has associated with it a set of type parameters (if it is a generic type definition) or type arguments (if it is a constructed type). A generic method differs from an ordinary method in the same way.

How do you declare a generic method How do you invoke a generic method?

Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.

Which of these is a correct way of defining generic method C#?

Which of these is a correct way of defining generic method? Explanation: The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type. 9.


2 Answers

Overload resolution is done at compile time, not at runtime. So when you call new C(v) from the Add<T> method, the compiler doesn't know that T will actually be Guid, so it uses the only overload that is guaranteed to be compatible, which is public C(object c)

like image 92
Thomas Levesque Avatar answered Sep 27 '22 18:09

Thomas Levesque


Generics in C# do not work the same as C++ templates - they are not expanded at compile time based on the usage. A single method is created and the methods called from within it are resolved statically.

Therefore, within Add, v can be any type, so the only thing known about it is that inherits from object so the object constructor for C is the only candidate.

To get the behaviour you want you'll have to add another overload of Add e.g.

public void Add(Guid g) { cs.Add(new C(g)); }
like image 20
Lee Avatar answered Sep 27 '22 17:09

Lee