0

理解できないコードに出くわしましたが、それも機能しない可能性があります。以下にコードを示します。

コンテキストで理解しようとするコード

メソッドはDataRowオブジェクトの配列を返しますGetDataTableData(): . 私が知る限り、 Select() 内のラムダは無効です。System.Data.DataTableSelect(...)DataRow[] rows

    var table = GetDataTableData()
                 .Select(s => new { s.Index })
                 .AsEnumerable()
                 .Select(
                     (s, counter) => new { s.Index, counter = counter + 1 }
                 );

私の質問: このラムダは何をしますか?有効/機能していますか?

メソッドSelect(...)には、すべて文字列型で始まるいくつかのオーバーロードがあります。

  • ラムダ式を文字列型にすることはできますか?
  • ラムダの戻り値の型は何ですか - 常にデリゲートですか?

ここで問題の行を上から

    // of what type is this (a delegate?)
    s => new { s.Index } 
    ... 
    // and what does this
    (s, counter) => new { s.Index, counter = counter + 1 }

以下の回答を読んだ後に更新してください

私が理解している限り、少なくとも 2 番目の Select は参照しています。しかし、コレクションIEnumerable.Select<T>を呼び出しAsEnumerable()ても、基になる型は変更されません。

    // calling AsEnumberable() does not change type
    IEnumerable<DataRow> enumDataRows = GetDataTable().AsEnumerable();
    Type type = enumDataRows.GetType().GetGenericArguments()[0]; 
    type.Dump(); // still returns DataRow

したがって、ラムダ式(s) => { return new { s.Index }; }が機能するには、基になる型にプロパティ Index が存在する必要があります。

この仮定は正しいですか?

最初の選択について

Select()それが組み込みまたは列挙可能なメソッドであることをどのように認識しますかEnumerable.Select<TSource, TResult>

それでも、tSource の基になるオブジェクト DataRow にはプロパティがないため、ステートメントはまだ有効ではないと思いますIndex

    var tResult = GetDataTable().Select(
                      (tSource, tResult) => { return new { tSource.Index }; }
                      );

この仮定は正しいですか?

4

2 に答える 2

1

どちらも匿名オブジェクトになるラムダです。また、どちらも非常に簡潔な形式で書かれています。完全な形式は次のようになります。

(s) => { return new { s.Index }; }

2番目は同等です。

どちらのラムダもFunc<>デリゲートであり、さまざまな署名があります。

ラムダは文字列になる可能性がありますが、それは何に使用するかによって異なります (ここでは型推論が非常に重要であり、ラムダが非常に簡潔である理由の 1 つです)。

ラムダの戻り値の型は、それを使用しているコンテキストによって異なります.デリゲートにすることもできますが、あなたの場合はそうではありません. ただし、ラムダはデリゲートです。戻り値の型がある場合はFunc<T1, T2, ... Tn, TReturn>、そうでない場合はAction<T1,T2,..., Tn>です。

于 2013-07-13T10:30:48.330 に答える