Q:

Creating Key/Value collections using LINQ To Objects

I'm trying to use LINQ To Objects to create a query that will give me files, indexed by filename with a value mapping to their binary data as byte[].
However I can't find a 'neat' way to do this. I'm hoping to get something like a Dictionary<T,K> output.
Here's what I have so far. Example 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);

The main head scratcher is why I can't use a parameterless ToDictionary(), or a direct cast. Any suggestions or alternatives to improve the above are appreciated.

A:

ToDictionary() would have to have a special case for KeyValuePair - which you could add as your own extension method of course:
public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(
     IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToDictionary(kvp => kvp.Key, kvp=> kvp.Value);
}

Without that extension method, you could do it like this:
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));

Basically the query expression allows you to do all the funky "let" stuff, but forces you to have a select at the end, which makes you propagate the two different values (the key and the byte array) into two properties.

