我有以下代码
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)));
}
}
但是,由于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
现在,很明显MyTargetClass实现了ITargetClass,但是编译器没有对此进行处理。
现在,我正在显式转换(ITargetClass)new MyTargetClass(v)
但是,为什么会首先发生这种情况,并且有更好的方法来解决此问题?
编译器不会自动转换IEnumberable<X>
到IEnumerable<Y>
即使X : Y
因为IDictionary
不是协变。在此讨论其基本原理:IDictionary <,>逆方差?和.NET 4中的IDictionary <TKey,TValue>不协变
至于绕过它,就像您提到的那样,您必须强制转换:
使用Cast扩展方法:
kvp => kvp.Value.Select(v => new MyTargetClass(v)).Cast<ITargetClass>()
显式转换:
kvp => kvp.Value.Select(v => (ITargetClass) new MyTargetClass(v))
更新:
只是因为和之间的混淆IEnumerable
而对此进行了扩展IDictionary
。IEnumerable
是协变的。IDictionary
不是。
很好:
IEnumerable<ITargetClass> list = new List<MyTargetClass>();
这不是:
IDictionary<object, IEnumerable<ITargetClass>> dict =
new Dictionary<object, List<MyTargetClass>>();
IDictionary
继承自IEnumerable<KeyValuePair<TKey, TValue>>
。有争议的是KeyValuePair
哪个不是协变的,哪个IDictionary
不是协变的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句