3

LINQ To Objectsを使用して、ファイル名でインデックス付けされ、バイナリデータにマッピングされた値を持つファイルを取得するクエリを作成しようとしていますbyte[]

しかし、私はこれを行うための「きちんとした」方法を見つけることができません。出力のようなものを取得したいと思っていDictionary<T,K>ます。

これが私がこれまでに持っているものです。例delimFileNames="1.jpg | 2.jpg"

//Extract filenames from filename string
//and read file binary from file
//select result into a filename indexed collection
var result = from f in delimFileNames.Split(Constants.DDS_FILENAME_SEPARATOR)
            let filePath = Path.Combine(ddsClient.WorkingDirectory, f)
            let fileData = File.ReadAllBytes(filePath)
            select new KeyValuePair<string, byte[]>(f, fileData);

return result.ToDictionary(kvp => kvp.Key, kvp=> kvp.Value);

主なヘッドスクラッチャーは、パラメーターなしのToDictionary()または直接キャストを使用できない理由です。上記を改善するための提案や代替案をいただければ幸いです。

4

3 に答える 3

5

ToDictionary()KeyValuePairの特別なケースが必要になります。もちろん、独自の拡張メソッドとして追加できます。

public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(
     IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToDictionary(kvp => kvp.Key, kvp=> kvp.Value);
}

その拡張メソッドがなければ、次のように実行できます。

var result = from f in delimFileNames.Split(Constants.DDS_FILENAME_SEPARATOR)
                                     .ToDictionary(f => f,
          // Outdented to avoid scrolling
          f => File.ReadAllBytes(Path.Combine(ddsClient.WorkingDirectory, f));

基本的に、クエリ式を使用すると、すべてのファンキーな「let」処理を実行できますがselect、最後にaを指定する必要があります。これにより、2つの異なる値(キーとバイト配列)が2つのプロパティに伝播されます。

于 2009-09-10T13:57:00.563 に答える
2

「主なヘッドスクラッチャーが、パラメーターなしの ToDictionary() を使用できない理由です [...]」

ToDictionaryメソッドは何がキーで何が値かを知る必要があるためです。マイクロソフトは、この特殊なケースのためにオーバーロードを作成できたかもしれませんが、作成しなかったのは、利点がそれほど大きくないと私が思うからです。しかし、まさにそれを行う独自の拡張メソッドを作成することを妨げるものは何もありません。

「[...] または直接キャスト。」

Linq クエリがIEnumerable<KeyValuePair<TKey, TValue>>ではない を返すためDictionary<TKey, TValue>です。キーと値のペアを列挙することはできますが、キーによる迅速な検索はできません。

これは、 Dictionary<TKey, TValue>LinqIEnumerable<KeyValuePair<TKey, TValue>>クエリで行ったのと同じようにキーと値のペアを反復処理できることを意味しますが、基になる型は Dictionary であるため、キーですばやく検索できます。 .

于 2009-09-10T14:10:17.913 に答える
1

を使用する必要はありません。代わりに、 andKeyValuePair<,>よりもわかりやすい名前を使用できる匿名型を使用できます。KeyValue

var files =
    from fileName in delimFileNames.Split(Constants.DDS_FILENAME_SEPARATOR)
    let filePath = Path.Combine(ddsClient.WorkingDirectory, fileName)
    select new
    {
        Path = filePath,
        Data = File.ReadAllBytes(filePath)
    };

return files.ToDictionary(file => file.Path, file => file.Data);
于 2009-09-10T15:09:40.080 に答える