17

Ok so I'm a Java guy starting to use C# and I was coding and started making a generic method and what I wrote runs and compiles but it goes against everything I know about how generics should work so I'm hoping someone can explain this to me:

So I have a generic method defined as follows:

public static List<T> CopyAsList<T>(IEnumerable<T> list, Object lockObject)  
{  
    if (list != null)  
    {  
        lock (lockObject)  
        {  
            return new List<T>(list);  
        }  
    }  
    return null;  
}  

But the weird thing to me is that I can call this generic method without ever specifying T and it will work:

List<String> strings = new List<string>() { "a", "b", "c"};
List<int> ints = new List<int>() { 1,2,3};
object lockObject = new object();

foreach (string s in CopyAsList(strings, lockObject))
{
    Console.WriteLine(s);
}

foreach (int i in CopyAsList(ints, lockObject))
{
    Console.WriteLine(i);
}

How is it the code is able to compile without ever specifying the generic type? Does C# infer the type at runtime?

Jeff Swensen
  • 3,513
  • 28
  • 52
Ian Dallas
  • 12,451
  • 19
  • 58
  • 82
  • 6
    There is no C# anymore at runtime. – Gabe Feb 12 '11 at 03:42
  • The C# compiler infers the type at compile time. On a side note, the CLR (DLR) can infer the type at run time, see the `dynamic` keyword from C#. – kizzx2 Feb 12 '11 at 05:46
  • 1
    kizzx2: The OP tagged the question with `.net-3.5` which eliminates `dynamic` from the context, and at runtime there is no type inferencing -- the DLR uses reflection to determine types. – Gabe Feb 12 '11 at 07:46

2 Answers2

35

No, it is inferred at compile time - the generic type parameter in the IEnumerable<T> you supply is used, which is known at compile time. Generally put, everything concerning generics and type parameters is specified at compile time. If there is mismatch of any kind, the compiler will complain and your code won't compile.

There are edge cases where you have to specify the types explicitly, these only occurs in rare circumstances with overloaded methods, sometimes with multiple combinations of type parameters.

Femaref
  • 60,705
  • 7
  • 138
  • 176
  • One of those circumstances is when any argument to a method is typed dynamic - once you throw that in there all compiler generic type inference is out the window, even if all the same clues are there. – Chris Moschini Jan 22 '13 at 21:28
13

The C# compiler can often infer the generic type at compile time. When it can do this, you do not need to specify the type for a generic method.

This is a major part of what makes LINQ "usable". Without compile time type inference, queries would look like:

IEnumerable<int> myIds = myCollection
                             .Where<MyType>(i => i.Name == "Foo")
                             .Select<MyType, int>(i => i.Id);

Instead of being able to write:

var myIds = myCollection.Where(i => i.Name == "Foo").Select(i => i.Id);
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 3
    and queries with anonymous types would be impossible, also, if the type wouldn't be inferable by the compiler, the code won't compile. – Femaref Feb 12 '11 at 00:23
  • Without type inference, the compiler wouldn't know what types those lambdas would have either. – Gabe Feb 12 '11 at 03:57