Kez*_*zza 5 c# linq todictionary
我有以下代码
public class TestAdaptor
{
private interface ITargetClass
{
Guid Id { get; }
string Name { get; }
}
private class MyTargetClass : ITargetClass
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public MyTargetClass(MySourceClass source)
{
}
}
private class MySourceClass
{
public Guid Id { get; set; }
public string Name { get; set; }
}
private Dictionary<Guid, IEnumerable<ITargetClass>> ConvertItems(Dictionary<Guid, IEnumerable<MySourceClass>> source)
{
return source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Select(v => new MyTargetClass(v)));
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这不会编译,因为 ToDictionary 行会导致以下错误
Cannot implicitly convert type
'System.Collections.Generic.Dictionary<System.Guid,System.Collections.Generic.IEnumerable<TestAdaptor.TestAdaptor.MyTargetClass>>'
to
'System.Collections.Generic.Dictionary<System.Guid,System.Collections.Generic.IEnumerable<TestAdaptor.TestAdaptor.ITargetClass>>' ...\TestAdaptor.cs 38 20
Run Code Online (Sandbox Code Playgroud)
现在很明显 MyTargetClass 实现了 ITargetClass 但编译器没有选择它。
现在我明确地转换 (ITargetClass)new MyTargetClass(v)
但是为什么首先会发生这种情况,有没有更好的方法来解决这个问题?
编译器不会自动转换IEnumerable<X>
为IEnumerable<Y>
Even ifX : Y
因为IDictionary
不是协变的。这里讨论其基本原理:IDictionary<,> 逆变?.NET 4 中的IDictionary <TKey, TValue> 不是协变的
至于绕过它,就像你提到的,你必须施放:
使用 Cast 扩展方法:
kvp => kvp.Value.Select(v => new MyTargetClass(v)).Cast<ITargetClass>()
Run Code Online (Sandbox Code Playgroud)
显式转换:
kvp => kvp.Value.Select(v => (ITargetClass) new MyTargetClass(v))
Run Code Online (Sandbox Code Playgroud)
更新:
只是为了扩展这一点,因为IEnumerable
和之间存在混淆IDictionary
。IEnumerable
是协变的。IDictionary
不是。
这很好:
IEnumerable<ITargetClass> list = new List<MyTargetClass>();
Run Code Online (Sandbox Code Playgroud)
这不是:
IDictionary<object, IEnumerable<ITargetClass>> dict =
new Dictionary<object, List<MyTargetClass>>();
Run Code Online (Sandbox Code Playgroud)
IDictionary
继承自IEnumerable<KeyValuePair<TKey, TValue>>
. 问题在于哪个KeyValuePair
不是协变的,哪个使得IDictionary
不是协变的。
归档时间: |
|
查看次数: |
1644 次 |
最近记录: |