C# Generic Method Without Specifying Type
Asked Answered
M

2

18

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?

Methedrine answered 12/2, 2011 at 0:17 Comment(3)
There is no C# anymore at runtime.Convexity
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#.Deist
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.Convexity
F
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.

Fortunato answered 12/2, 2011 at 0:19 Comment(1)
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.Adolescence
E
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);
Efface answered 12/2, 2011 at 0:20 Comment(2)
and queries with anonymous types would be impossible, also, if the type wouldn't be inferable by the compiler, the code won't compile.Fortunato
Without type inference, the compiler wouldn't know what types those lambdas would have either.Convexity

© 2022 - 2024 — McMap. All rights reserved.