我有以下代码

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不是covariant。在此讨论其基本原理:IDictionary<,> contravariance?IDictionary<TKey, TValue> in .NET 4 not covariant
至于绕过它,就像您提到的那样,您必须强制转换:
使用Cast扩展方法:

 kvp => kvp.Value.Select(v => new MyTargetClass(v)).Cast<ITargetClass>()
显式转换:
 kvp => kvp.Value.Select(v => (ITargetClass) new MyTargetClass(v))
更新:
由于IEnumerableIDictionary之间的混淆,仅对此进行扩展。 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不协变。

关于c# - Linq ToDictionary不会隐式将类转换为接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25136049/

10-12 15:52