使用LINQ To Objects创建键/值集合

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()或直接转换。欢迎提出任何建议或改进上述方法的替代方案。
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,这使您将两个不同的值(键和字节数组)传播到两个属性中。


+1 我觉得你在潜伏,等待这些问题,Jon :P - Kyle Rosendo

2
"主要的疑问是为什么我不能使用无参数的ToDictionary()方法[...]"
因为ToDictionary()方法需要知道哪个是键,哪个是值。微软可以为这种特殊情况创建一个重载,但是他们没有这样做,可能是因为好处不是很大。但是你可以自己创建一个扩展方法来实现这一点。
"[...]或直接转换。"
因为您的Linq查询返回一个IEnumerable>,而不是Dictionary。它允许您枚举键/值对,但不允许通过键进行快速查找。
请注意,Dictionary确实是一个IEnumerable>(它实现了该接口),这意味着您可以像使用Linq查询一样遍历键/值对,但底层类型是Dictionary,因此可以通过键进行快速查找。"

1

你不需要使用 KeyValuePair<,>,相反你可以使用匿名类型,这样你就可以使用比 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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接