17

わかりましたので、私はC#を使い始めたJavaの男で、コーディングしてジェネリックメソッドを作成し始めました。私が書いたものは実行およびコンパイルされますが、ジェネリックがどのように機能するかについて私が知っているすべてに反するので、誰かがこれを説明できることを願っています私に:

したがって、次のように定義されたジェネリックメソッドがあります。

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

しかし、私にとって奇妙なことは、指定せずにこのジェネリックメソッドを呼び出すことができT、それが機能することです:

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);
}

ジェネリック型を指定せずにコードをコンパイルできるのはどうしてですか? C# は実行時に型を推測しますか?

4

2 に答える 2

35

いいえ、コンパイル時に推測されます - コンパイル時に認識される、指定したジェネリック型パラメーターIEnumerable<T>が使用されます。一般的に言えば、ジェネリックと型パラメーターに関するすべてはコンパイル時に指定されます。なんらかの不一致があると、コンパイラ文句を言い、コードはコンパイルされません。

型を明示的に指定しなければならないエッジケースがあります。これらは、オーバーロードされたメソッドを使用するまれな状況でのみ発生し、型パラメーターの複数の組み合わせがある場合もあります。

于 2011-02-12T00:19:37.730 に答える
12

C# コンパイラは、多くの場合、コンパイル時にジェネリック型を推測できます。これが可能な場合、ジェネリック メソッドの型を指定する必要はありません。

これは、LINQ を「使用可能」にする主要な部分です。コンパイル時の型推論がなければ、クエリは次のようになります。

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

書くことができる代わりに:

var myIds = myCollection.Where(i => i.Name == "Foo").Select(i => i.Id);
于 2011-02-12T00:20:05.473 に答える