Вопрос:

C# Generic Method Without Specifying Type

c# .net generics .net-3.5 generic-method

11673 просмотра

3 ответа

6515 Репутация автора

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?

Автор: Ian Dallas Источник Размещён: 12.02.2011 12:17

Ответы (3)


35 плюса

55254 Репутация автора

Решение

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 Размещён: 12.02.2011 12:19

11 плюса

486538 Репутация автора

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 Размещён: 12.02.2011 12:20

13 плюса

570204 Репутация автора

C# has a great many more compile-time and runtime type inference features than Java. If this subject interests you, see my articles on the subject:

http://blogs.msdn.com/b/ericlippert/archive/tags/type+inference/

If you are in particular interested in generic method type inference and you have half an hour to spare, here's me explaining how we changed the type inference algorithm in C# 3:

http://blogs.msdn.com/b/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx

Автор: Eric Lippert Размещён: 12.02.2011 07:42
Вопросы из категории :
32x32