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

时间:2010-01-27 16:02:01

标签: c# inheritance interface class-hierarchy explicit-interface

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

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> IDictionary<string, string>.Keys { }
}

然后我有了这个派生类:

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) { }
    }
}

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

4 个答案:

答案 0 :(得分:8)

您正在明确实施Keys属性。如果您希望公开访问该成员(或protected),请将IDictionary<string, string>.Keys更改为Keys,并在其前面添加相应的可见性修饰符。

public ICollection<string> Keys { ... }

protected ICollection<string> Keys { ... }

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

((IDictionary<string, string>)base).Keys

更多信息

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

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

public interface IMyInterface
{
    void Foo();
}

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

public class MyClass : IMyInterface
{
    public void Foo() { }
}

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

public class MyClass : IMyInterface
{
    void IMyInterface.Foo() { }
}

这会在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
}

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

答案 1 :(得分:3)

由于您正在实施IDictionary&lt; TKey,TValue&gt;明确地,您首先必须将this投射到IDictionary<string,string>

public bool Equals(MySubRow other)
{
    foreach (string key in ((IDictionary<string,string>)this).Keys) { }
}

答案 2 :(得分:0)

我相信Jared和Adam都是正确的:该属性是在基类上实现的,它导致它不公开。您应该能够将其更改为隐式实现并使其满意:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> Keys { }
}

答案 3 :(得分:0)

protected将允许继承类来查看它,但没有其他类