Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type inference for type arguments of generic methods

I'm a newby to Stack Overflow so please go easy on me! I'm reading C# in Depth but I've come across a scenario that I don't believe is covered. A quick search of the web didn't throw up any results either.

Say I define the following overloaded methods:

void AreEqual<T>(T expected, T actual)

void AreEqual(object expected, object actual)

If I call AreEqual() without specifying a type argument:

AreEqual("Hello", "Hello")

Is the generic or non-generic version of the method invoked? Is the generic method invoked with the type argument being inferred, or is the non-generic method invoked with the method arguments being implicitly cast to System.Object?

I hope my question is clear. Thanks in advance for any advice.

like image 205
zekesteer Avatar asked Jan 28 '12 01:01

zekesteer


People also ask

What is infer generic type arguments?

Type inference represents the Java compiler's ability to look at a method invocation and its corresponding declaration to check and determine the type argument(s). The inference algorithm checks the types of the arguments and, if available, assigned type is returned.

Which types can be used as arguments of generics?

Only reference types can be used as type arguments. A parameterized type such as List<int> or Set<short> is illegal. Only reference types can be used for instantiation of generic types and methods.

What is meant by type inference?

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.

Are generics type differ based on their type arguments?

Generic Types Differ Based on Their Type Arguments: Consider the following Java code.


1 Answers

The generics can generate a function AreEqual(string, string). This is a closer match than AreEqual(object, object), so therefore the generic function is chosen.

Interestingly, the compiler will choose this generic function even if it results in a constraint violation error.

Look at this example:

using System.Diagnostics;

namespace ConsoleSandbox
{
    interface IBar
    {
    }

    class Program
    {
        static void Foo<T>(T obj1) where T: IBar
        {
            Trace.WriteLine("Inside Foo<T>");
        }


        static void Foo(object obj)
        {
            Trace.WriteLine("Inside Foo Object");
        }

        static void Main(string[] args)
        {

            Foo("Hello");
        }
    }
}

Even HERE it will choose the generic version over the non-generic version. And then you get this error:

The type 'string' cannot be used as type parameter 'T' in the generic type or method 'ConsoleSandbox.Program.Foo(T)'. There is no implicit reference conversion from 'string' to 'ConsoleSandbox.IBar'.

But if you add a function Foo(string obj1) it will work.

like image 126
Andrew Shepherd Avatar answered Sep 22 '22 13:09

Andrew Shepherd