C# 中字典的隐式转换/多态性

问题描述 投票:0回答:1

我遇到了一个问题,我无法将

Dictionairy<int, class>
隐式转换为
Dictionairy<int, interfaceOfClass>
,我觉得这通常应该可以通过多态性规则实现。我目前的解决方法是像这样进行显式转换
class => class as interfaceOfClass

我不确定我的代码中是否缺少某些内容以使其正常工作,或者它是否是 C# 的限制。下面是我的问题的具体示例。

namespace ImplicitCasting;

internal class Program {
    static void Main(string[] args) {
        IDictionary<int, Person> persons = new Dictionary<int, Person> {
            { 0, new Person() { Name = "Person1", Age = 20 } },
            { 1, new Person() { Name = "Person2", Age = 30 } },
            { 2, new Person() { Name = "Person3", Age = 35 } }
        };

        /*
         This doenst work
         Gives error: CS0266    Cannot implicitly convert type
         'System.Collections.Generic.IDictionary<int, ImplicitCasting.Program.Person>' to
         'System.Collections.Generic.IDictionary<int, ImplicitCasting.Program.IPerson>'.
          An explicit conversion exists (are you missing a cast?)
        */
        //IDictionary<int, IPerson> implicitCast = persons;

        // This is what I need to do to make it work
        IDictionary<int, IPerson> explictCast = persons
            .ToDictionary(entry=>entry.Key, entry=>entry.Value as IPerson);

        foreach (var enrty in explictCast) {
            Console.WriteLine($"{enrty.Key}. Person: {enrty.Value.Name}");
        }
    }

    public interface IPerson {
        string Name { get; set; }
        void DoSomething();
    }

    public class Person : IPerson {
        public string Name { get; set; } = "Test";
        public int Age { get; set; }
        public void DoSomething() {
            Console.WriteLine($"{Name} doint something");
        }
    }
}

c# .net dictionary inheritance polymorphism
1个回答
0
投票

总体来说:
错误的原因是

IDictionary<int, IPerson>
IDictionary<int, Person>
不相关的类型,因此您无法将
persons
(即
IDictionary<int, Person>
)转换为
IDictionary<int, IPerson>

这里还有一个具体问题:
目前

persons
是一个字典,保存类
Person
(或从它派生的任何类)的对象。
但是,如果允许从
IDictionary<int, Person>
IDictionary<int, IPerson>
的转换,那么您就可以将
IPerson
派生对象添加到字典中,这些对象是 not
Person
(也不是从中派生的)。
这会破坏
persons
类型的安全保证。

最好的解决方案,如果它适用于您,请将

persons
更改为
IDictionary<int, IPerson>
。否则,您必须创建一个副本,就像您已经做的那样。

© www.soinside.com 2019 - 2024. All rights reserved.