5

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

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属性标记为publicin,MyRow但得到“修饰符 'public' 对此项目无效”,我认为是因为有必要实现接口。

4

4 回答 4

9

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

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,或者如果两个接口暴露了具有相同名称的成员。

于 2010-01-27T16:04:02.520 回答
3

由于您正在显式实现 IDictionary<TKey,TValue> 接口,因此您首先必须转换thisIDictionary<string,string>

public bool Equals(MySubRow other)
{
    foreach (string key in ((IDictionary<string,string>)this).Keys) { }
}
于 2010-01-27T16:05:29.943 回答
0

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

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> Keys { }
}
于 2010-01-27T16:05:46.630 回答
0

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

于 2010-01-27T16:05:53.997 回答