2017-04-03 7 views
1

Enumerable.Aggregateには3つのオーバーロードバージョンがあります。 official exampleで使用されているものと一致するこの関数のオーバーロードバージョンは見つかりませんでした。C#集約関数の定義の説明

public static TSource Aggregate<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, TSource, TSource> func 
) 

上記の定義は、この公式の例とは全く異なります。ここでは

string sentence = "the quick brown fox jumps over the lazy dog"; 

// Split the string into individual words. 
string[] words = sentence.Split(' '); 

// Prepend each word to the beginning of the 
// new sentence to reverse the word order. 
string reversed = words.Aggregate((workingSentence, next) => 
             next + " " + workingSentence); 

Console.WriteLine(reversed); 

// This code produces the following output: 
// 
// dog lazy the over jumps fox brown quick the 

は、集計関数の3つのオーバーロードバージョンです:それらの

public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func); 

public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func); 

public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector); 

なしで使用される機能と一致していません上記の例。公式文書は間違っていますか?または私はsthを逃した? 3つのバージョンの関数定義とこの公式の例の間のギャップを埋めるのを助けてください。

機能定義の理解方法は?

+0

実際に最初に過負荷を言いました**は**その公式の例で使用されているものと同じです**。 – Evk

+0

[拡張方法](https://msdn.microsoft.com/en-us/library/bb383977.aspx)を確認してください。 –

答えて

3
public static TSource Aggregate<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, TSource, TSource> func 
) 

これは、実際に公式の例で使用したものである:

string reversed = words.Aggregate((workingSentence, next) => 
             next + " " + workingSentence); 

あなたを混乱されるかもしれないいくつかの作品は以下のとおりです。sourceパラメータの前に

  1. thisキーワードこれは拡張メソッドとして識別されます。つまり、上記のコードは次の構文の砂糖です。

    string reversed = Enumerable.Aggregate(words, (workingSentence, next) => 
                next + " " + workingSentence); 
    
  2. TSourceコンパイラはINFERwordsIEnumerable<string>であるという事実から、このタイプすることが可能であるため、この場合にstringで置換されている一般的なパラメータです。

  3. Func<TSource, TSource, TSource>は、2つのパラメータ(最初の2つのTSource)を取り、TSourceを返す関数を表す汎用代理人です。これは、2つのパラメータをとり、値を返さないAction<TSource, TSource>とは対照的です。これらの型のいずれかは、形式が(param1, param2) => expressionのラムダ式で表すことができます。

+0

Func funcは3つのパラメータをとりますか?または最初の2つは2つのparam型です.3番目の型はreturn型ですか? –

+0

@ NicolasS.Xu:後者。私の更新を参照してください。 – StriplingWarrior

2

投稿した例では、投稿した最初のオーバーロードが使用されています。それはあなたを捨てている拡張メソッドなのかもしれません。

拡張メソッドの場合、thisパラメータは、呼び出されたインスタンスへの参照になります。コードがコンパイルされると、適切な静的メソッド呼び出しに変換されます。

words.Aggregate((workingSentence, next) => 
            next + " " + workingSentence); 

それはこのにコンパイルされます:あなたは、これは書くとき基本的には、

Enumerable.Aggregate<string>(words, (workingSentence, next) => 
            next + " " + workingSentence); 
1

this修飾子は、過負荷がExtension Methodであることを示しています。

この場合、メソッド定義のthis IEnumerable<TSource> sourceは、この例ではwordsに相当します。

1

公式文書は完全に正しいです。公式の例では、次のシグネチャが使用されている:

public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func); 

列のアレイはIEnumerableをソースと一致するように、それは、文字列[]語拡張法です。そして、次のコードは、のFunc FUNCと一致している:

Func<string, string, string> func = (workingSentence, next) => next + " " + workingSentence; 
words.Aggregate(func); 

FUNCにおける二つの最初の文字列が入力され、最後の1本であること戻り値の型である:あなたが書くことができますつまり

(workingSentence, next) => next + " " + workingSentence 

例は2つの文字列の集約です。