Frage

Ich bin nicht sicher, was los ist. Ich habe die folgende Basisklasse:

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

Und dann habe ich diese abgeleitete Klasse:

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

Warum erhalte ich diesen Fehler? „‚MyNamespace.MyRow‘enthält keine Definition für‚Keys‘“. Beide Klassen sind im MyNamespace Namespace. Ich habe versucht, Zugriff auf this.Keys und base.Keys und weder Werke aus MySubRow. Ich versuchte, die Keys Eigenschaft als public in MyRow Markierung bekam aber „Der Modifikator‚öffentlich‘für diesen Titel nicht gültig ist“, ich glaube, weil es notwendig ist, eine Schnittstelle zu implementieren.

War es hilfreich?

Lösung

Sie sind die Umsetzung der Keys Eigenschaft explizit. Wenn Sie möchten, dass das Mitglied öffentlich zugänglich machen (oder protected), ändert IDictionary<string, string>.Keys zu Keys und fügen Sie die entsprechenden Sichtbarkeitsmodifizierer vor ihm.

public ICollection<string> Keys { ... }

oder

protected ICollection<string> Keys { ... }

Sie könnten base als Instanz IDictionary<string, string> Referenz auch:

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

Weitere Informationen:

(nach zu urteilen Ihre Kommentare erscheinen Sie mit dem Unterschied vertraut zu sein, aber andere können nicht sein)

C # Schnittstellen-Implementierung kann auf zwei Arten erfolgen: implizit oder explizit. Betrachten wir diese Schnittstelle:

public interface IMyInterface
{
    void Foo();
}

Eine Schnittstelle ist nur ein Vertrag für das, was Mitglieder einer Klasse muss, um Code zur Verfügung stellen, die es aufruft. In diesem Fall haben wir eine Funktion namens Foo, die keine Parameter und gibt nichts nimmt. Eine implizite Schnittstellen-Implementierung bedeutet, dass Sie ein public Mitglied aussetzen müssen, die den Namen und die Unterschrift des Mitglieds an der Schnittstelle übereinstimmt, wie folgt aus:

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

Dies erfüllt die Schnittstelle, weil es ein public Mitglied auf der Klasse macht, dass jedes Mitglied an der Schnittstelle übereinstimmt. Dies ist, was in der Regel geschieht. Es ist jedoch möglich, explizit die Schnittstelle implementieren und die Schnittstellenfunktion zu einem private Mitglied Karte:

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

Dies schafft eine private Funktion auf MyClass, die nur von externen Anrufern ist, wenn sie auf eine Instanz IMyInterface beziehen. Zum Beispiel:

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

    class1.Foo(); // works only in the first implementation style
    class2.Foo(); // works for both
}

Explizite Implementierungen sind immer privat. Wenn Sie es außerhalb der Klasse aussetzen möchten, müssen Sie ein anderes Mitglied erstellen müssen und setzen, dass dann die explizite Implementierung verwenden, um die anderen Mitglied zu nennen. Dies erfolgt in der Regel so, dass ein Klasse-Schnittstellen ohne unübersichtlich seine öffentliche API implementieren kann, oder wenn zwei Schnittstellen Mitglieder mit dem gleichen Namen aus.

Andere Tipps

Da Sie die IDictionary sind Implementierung Schnittstelle explizit, Sie zuerst gegossene this zu IDictionary<string,string> haben:

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

ich glaube, beide Jared und Adam sind korrekt: die Eigenschaft explitcity auf der Basisklasse implementiert ist, was es nicht öffentlich zu sein. Sie sollten es zu ändern, um eine implizite Umsetzung der Lage sein, und machen es glücklich:

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

protected wird Vererbungsklassen erlauben es, um zu sehen, aber keine andere Klasse

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top