0

私はジェネリックにかなり慣れていますが、すべての詳細を理解するのが好きな人なので、この質問があります. Where私のLINQ拡張メソッドの実装では

    public static class Extensions
    {
        public static IEnumerable<T> Where<T>(
                         this IEnumerable<T> source, Func<T, bool> predicate)
        {
            foreach (T element in source)
                if (predicate(element))
                    yield return element;
        }
    }

なぜ必要なのTですか?inWhere<T>から型を推測できないのはなぜですか? 言い換えれば、なぜ署名ができないのかTIEnumerable<T>

public static IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> predicate)

助けてくれてありがとう。

4

5 に答える 5

4

public static IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> predicate)

このような署名でTは、宣言されていない識別子になります。ifがどこにも定義されていないIEnumerable<T>場合は、そのまま使用することはできません。したがって、意味を成すには、メソッド (またはクラス) レベルでT汎用パラメーターが必要です。TIEnumerable<T>

于 2013-01-15T23:21:51.150 に答える
2

とが同じものでなければならTないという理由はまったくありません。あなたは、それらの両方を次のように指定することによって、そうでなければならないと言っていますIEnumerable<T>Where<T>T

IEnumerable<T>メソッドによって返されるものです。Where<T>パラメーターとして使用されるジェネリック型が何であるかを定義するためのものです。両方TT

つまり、戻り値の型 ( IEnumerable<T>) は、必ずしもパラメーターの型 ( の ) に関連しているわけではありませTWhere<T>

于 2013-01-15T23:23:53.053 に答える
1

<T>引数リストの前に付けることは、「変数宣言」のように振る舞います-ただ言うことはできません:

x = 10;

最初にその変数を宣言する必要があります。

int x = 10;

ここにあるのは a の変数宣言ですType

今、使用法Type、それはまったく別のことです-コンパイラーは、使用法と既存の署名に基づいて、これらの変数のそれぞれにどの「値」を固定するかを推測しようとしますが、それらの署名はまだ宣言する必要があります。

于 2013-01-15T23:21:47.823 に答える
1

メソッドの定義とその使用法を混在させています。Where<T>

関数を定義(および宣言) するときは、メソッドがジェネリックであることをコンパイラーに示すために、そこに型パラメーターが必要です。型パラメーターを宣言するとT、それを使用して、入力引数と出力引数の型 (この場合は ) を示すことができますIEnumerable<T>

メソッドを使用する場合、指定する必要はありません。最初の入力引数から十分に推測できます。よくわからない場合は、次のことを試してください。

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var odds = numbers.Where(x => x % 2 != 0);

// test for example odds is IEnumerable<int> if you want confirmation =)
于 2013-01-15T23:34:16.093 に答える
0
public static class Foo
{
    public static T Bar<T>(T input) { return input; }
}

通常、型は推測されます。

Foo.Bar("test");

しかし、この場合はどうなりますか?

Foo.Bar(null); //error

型引数は推論できません。これがコンパイル時に行われた場合、コンパイル エラーが発生します。

Foo.Bar<string>(null); //works
于 2013-01-15T23:33:29.340 に答える