首页 > 解决方案 > 试图理解 C# 嵌套接口

问题描述

我试图获得一组简单的嵌套接口,以便我可以在派生类上强制执行一些成员。

 public enum Category { Mental, Physical, Technical }

        interface IAbilities
        {
            List<IAbility> Abilities { get; set; }
        }

        interface IAbility
        {
            Category Category { get; }
            int Value { get; set; }
            string Descritpion { get; set; }
        }

        public class MentalAbilities : IAbilities
        {
            // This is what I want so that "Abilities" is accessible
            public List<MentalAbility> Abilities { get; set; }

            // This is what Intellisense generates, cannot be set to public
            //List<IAbility> IAbilities.Abilities { get; set; }
        }

        public class MentalAbility : IAbility
        {
            public Category Category { get; } category
            public int Value { get; set; }
            public string Descritpion { get; set; }
        }

当然,Intellisense 生成的位编译,但“能力”不能从类实例访问,因为它不能设置为公共。

我想要的一点告诉我“MentalAbilities”没有实现接口成员“IAbilities.Abilities”。“MentalAbilities.Abilities”无法实现“IAbilities.Abilities”,因为它没有 List<IAbility> 的匹配返回类型。

我不明白,因为“MentalAbility”是从“IAbility”接口派生的,所以应该履行合同。

标签: c#nested

解决方案


(我跳过了“x 比 y 更难访问”的错误,因为你已经知道你可以公开你的接口 - 确保你可以理解任何东西必须至少与它的使用一样可访问)

重新您的“未实施”错误:

我理解你的问题,但你有点颠倒了

我看到你想确保,在你的 MentalAbility.Abilities 列表中,有人只放置 MentalAbility 对象.. 他们实现 IAbility 所以它应该满足“对象是一个 IAbility 并且有一个列表只包含实现 IAbility 的东西”规则,对?

唉,没有。这与继承或接口实现的用途几乎相反。

继承背后的想法是,你可以说“这个东西可以是任何类型,只要它有这些共同的方面,我会以共同的方式对待它”。通过这样声明,List<IAbility>您是在说“此列表中的对象只需要实现 IAbility,然后我就可以处理它们”——它可能是 MentalAbility 或 PhysicalAbility——没关系

然后,您不能通过继承/实现机制将列表限制为仅包含 MentalAbility,也不应该因为它与从“我可以处理任何事情只要它实现 X”到“我只会处理如果它是 Y 的子类型,或者是 Y 的子类型,则它与之前声称的相反。你是说 MentalAbility 只能处理列表内容,如果它们是 MentalAbility,当你之前说它可以处理任何 IAbility 时

如果您想强制 MentalAbility 仅包含 MentalAbility,则必须将其声明为List<IAbility>并查看您在集合中给出的 IAbility 的类型,如果它不是 MentalAbility,但如果其他开发人员使用,则拒绝添加它你的代码他们会很困惑——“什么?它说我可以使用任何实现 IAbility 的东西,而我的 TigerAbility 就是这样做的。为什么我得到一个异常,它必须是 MentalAbility?为什么这个开发人员甚至如果我不允许将任何我喜欢的 IAbility 放入其中,请使用 List(IAbility)?” - 它也不再是编译时的事情,而是运行时的事情,这是一个很大的风险

我认为您需要决定是否能够以通用方式处理这些事情,即您的 AbilitiesProcessor 是否可以实现 IAbility 并拥有一个 IAbility 列表并不管实际类型如何处理它们。如果它不能,并且您将拥有一个只能处理 MentalAbility 的 MentalAbility 类,这很好,并且它可以拥有List<MentalAbility>它想要的一切,其他开发人员不会错误地将 TigerAbility 放入其中,但它不会t 实现 IAbilities 接口


推荐阅读