Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图理解C#嵌套接口_C#_Nested - Fatal编程技术网

试图理解C#嵌套接口

试图理解C#嵌套接口,c#,nested,C#,Nested,我正在尝试嵌套一组简单的接口,以便在派生类上强制执行一些成员 public enum Category { Mental, Physical, Technical } interface IAbilities { List<IAbility> Abilities { get; set; } } interface IAbility { Category

我正在尝试嵌套一组简单的接口,以便在派生类上强制执行一些成员

 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; }
        }
公共枚举类别{心理、物理、技术}
接口可靠性
{
列出能力{get;set;}
}
接口可靠性
{
类别{get;}
int值{get;set;}
字符串描述符{get;set;}
}
公共类可用性:可用性
{
//这就是我想要的,这样“能力”就可以访问
公共列表能力{get;set;}
//这是Intellisense生成的,不能设置为公共
//列出能力。能力{get;set;}
}
公共类可扩展性:可扩展性
{
公共类别类别{get;}类别
公共int值{get;set;}
公共字符串描述符{get;set;}
}
当然,Intellisense生成的位可以编译,但是“能力”不能从类实例访问,因为它不能设置为public

我想要的信息告诉我,“'MentalAbilities'没有实现接口成员'IAbilities.Abilities'MentalAbilities.Abilities“无法实现”IAbilities.Abilities“,因为它没有匹配的列表返回类型


我不明白,因为“可扩展性”是从“可扩展性”接口派生出来的,所以它应该满足合同。

您所坚持的是C#中接口的隐式和显式实现。如果您这样定义类成员:

public List<MentalAbility> Abilities { get; set; }
public abstract class AbilitiesBase<A> : IAbilities<A> where A : IAbility
{
    public List<A> Abilities { get; protected set; }
    List<IAbility> IAbilities.Abilities => this.Abilities.Cast<IAbility>().ToList();
}
您已经显式地实现了
iability
,在这种情况下,它可以是私有的

在这里,我认为没有必要定义接口
iability
。你应该在任何你想使用
iability
的地方简单地使用
IEnumerable
,这实际上在你的代码中没有提供任何价值。

(我跳过了“x比y更难访问”错误,因为您已经确定可以将接口公开-确保您能够理解任何东西都必须至少与使用时一样可访问)

关于您的“未实现”错误:

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

我知道你想确保,在你的MentalAbilities.Abilities列表中,有人只放置MentalAbilities对象。。他们实现了可移植性,所以它应该满足“对象是可移植性,并且有一个列表,其中只包含实现可移植性的东西”规则,对吗

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

继承背后的想法是,你可以说“这个东西可以是任何类型的,只要它有这些共同的方面,我将以共同的方式对待它”。通过声明
List
你是说“这个列表中的对象只需要实现可扩展性,然后我就可以处理它们”——它可以是一个可扩展性,也可以是一个物理可扩展性——这无关紧要

然后,您不能通过继承/实现机制将列表约束为仅包含MentalAbility,您也不应该这样做,因为它与它的用途相反——从“只要它实现了X,我就可以处理任何事情”到“如果它是Y或Y的子类型,我将只处理某件事情”与前面声明的相反。你的意思是,当你早些时候说它可以处理任何不可处理的内容时,如果它是可处理的,那么它只能处理列表内容

如果你想强制MentalAbilities只包含MentalAbility,你必须将它声明为
列表
,并查看你在集合中给出的可用性类型,如果不是MentalAbility,就拒绝添加它,但如果其他开发人员使用你的代码,他们会非常困惑-“什么?它说我可以使用任何实现可移植性的东西,而我的可移植性正是这样做的。。为什么我会得到一个例外,那就是它必须是一个可扩展性?如果不允许我将任何我喜欢的可维护性添加到列表中,为什么这个开发人员还要使用列表(可维护性)?-这也不再是编译时的事情,而是运行时的事情,这是一个很大的风险

我认为你需要决定你是否能够以一种通用的方式来处理这些事情,也就是说,你的AbilitiesProcessor是否能够实现Abilities并有一个Abilities列表,不管实际类型如何处理它们。如果不能,你将有一个MentalAbilities类,它只能处理MentalAbility,这很好,而且可以拥有一个
列表
所有它想要的,其他开发人员不会错误地将可操作性放入其中,但它不会实现可操作性接口

我正在尝试嵌套一组简单的接口,以便在派生类上强制执行一些成员

 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; }
        }
这里的主要问题是默认情况下将两个接口定义为
private
。这就是阻止您在
MentalAbilities
内部创建
public List能力{get;set;}

实际上,属性
public-List-Abilities{get;set;}
也阻止了您,因为您不能两次定义相同名称的属性

这里的大问题是允许
MentalAbilities
设置
列表的能力有什么意义,因为这意味着设置任何类型的能力

理想情况下,
MentalAbility
应该只有一个它包含的
MentalAbility
列表,并且它应该是只读的。事实上,大多数接口都应该是只读的

以下是您应该做的:

从以下接口开始:

public interface IAbilities<A> where A : IAbility
{
    List<A> Abilities { get; }
}

public interface IAbility
{
    Category Category { get; }
    int Value { get; }
    string Description { get; }
}
public interface IAbilities
{
    List<IAbility> Abilities { get; }
}

public interface IAbilities<A> : IAbilities where A : IAbility
{
    new List<A> Abilities { get; }
}
现在,最后的课程很简单:

public class MentalAbilities : AbilitiesBase<MentalAbility> { }

public class MentalAbility : AbilityBase
{
    public override Category Category => Category.Mental;
    public override int Value => 42;
    public override string Description => "Mental!";
}
这将强制更改
能力库
,如下所示:

public List<MentalAbility> Abilities { get; set; }
public abstract class AbilitiesBase<A> : IAbilities<A> where A : IAbility
{
    public List<A> Abilities { get; protected set; }
    List<IAbility> IAbilities.Abilities => this.Abilities.Cast<IAbility>().ToList();
}
公共抽象类能力base:IAbility其中A:IAbility
{
公开列表能力{