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.Keys内からandにアクセスしようとbase.Keysしましたが、どちらも機能しませんMySubRowKeysプロパティを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# インターフェイスの実装は、暗黙的または明示的な 2 つの方法で行うことができます。このインターフェースを考えてみましょう:

public interface IMyInterface
{
    void Foo();
}

インターフェイスは、クラスを呼び出しているコードがクラスを使用できるようにする必要があるメンバーの単なる契約です。この場合、Fooパラメーターをとらず、何も返さない 1 つの関数が呼び出されます。暗黙的なインターフェイスの実装は、次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 を乱雑にすることなくインターフェイスを実装できるようにするため、または 2 つのインターフェイスが同じ名前のメンバーを公開する場合に行われます。

于 2010-01-27T16:04:02.520 に答える
3

IDictionary<TKey,TValue> インターフェイスを明示的に実装しているため、最初に次のようにキャストthisする必要がありIDictionary<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 に答える