C#属性在派生类中不可用

Sar*_*els 5 c# inheritance interface explicit-interface class-hierarchy

我不确定发生了什么.我有以下基类:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> IDictionary<string, string>.Keys { }
}
Run Code Online (Sandbox Code Playgroud)

然后我有这个派生类:

public class MySubRow : MyRow, IXmlSerializable, ICloneable,
    IComparable, IEquatable<MySubRow>
{
    public bool Equals(MySubRow other)
    {
        // "MyRow does not contain a definition for 'Keys'"
        foreach (string key in base.Keys) { }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我会收到这个错误?"'MyNamespace.MyRow'不包含'Keys'的定义".这两个类都在MyNamespace命名空间中.我试过访问this.Keys,base.Keys并且都没有从内部工作MySubRow.我尝试将Keys属性标记为public,MyRow但得到"修饰符'公共'对此项无效",我认为因为有必要实现一个接口.

Ada*_*son 9

您正在Keys显式实现该属性.如果你想使该成员公开访问(或protected)改变IDictionary<string, string>.KeysKeys和在它前面添加相应的可见性修饰符.

public ICollection<string> Keys { ... }
Run Code Online (Sandbox Code Playgroud)

要么

protected ICollection<string> Keys { ... }
Run Code Online (Sandbox Code Playgroud)

您也可以引用base作为实例IDictionary<string, string>:

((IDictionary<string, string>)base).Keys
Run Code Online (Sandbox Code Playgroud)

更多信息

(根据你的评论,你似乎熟悉这种区别,但其他人可能不是)

C#接口实现可以通过两种方式完成:隐式或显式.让我们考虑一下这个界面:

public interface IMyInterface
{
    void Foo();
}
Run Code Online (Sandbox Code Playgroud)

接口只是一个类,它必须为调用它的代码提供哪些成员.在这种情况下,我们有一个调用的函数Foo,它不带任何参数,也不返回任何参数 隐式接口实现意味着您必须公开public与接口上成员的名称和签名匹配的成员,如下所示:

public class MyClass : IMyInterface
{
    public void Foo() { }
}
Run Code Online (Sandbox Code Playgroud)

这满足了接口,因为它公开了public类上与接口上的每个成员匹配的成员.这就是通常所做的事情.但是,可以显式实现接口并将接口函数映射到private成员:

public class MyClass : IMyInterface
{
    void IMyInterface.Foo() { }
}
Run Code Online (Sandbox Code Playgroud)

这创建了一个私有函数MyClass,只有外部调用者在引用其实例时才能访问IMyInterface.例如:

void Bar()
{
    MyClass class1 = new MyClass();
    IMyInterface class2 = new MyClass();

    class1.Foo(); // works only in the first implementation style
    class2.Foo(); // works for both
}
Run Code Online (Sandbox Code Playgroud)

显式实现始终是私有的.如果要在类之外公开它,则必须创建另一个成员并公开它,然后使用显式实现来调用其他成员.通常这样做是为了使类可以实现接口而不会混乱其公共API,或者如果两个接口公开具有相同名称的成员.