Domanda

Non sono sicuro di quello che sta succedendo. Ho la seguente classe di base:

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

E poi ho questa classe derivata:

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

Perché ottengo questo errore? " 'MyNamespace.MyRow' non contiene una definizione di 'Keys'". Entrambe le classi sono nello spazio dei nomi MyNamespace. Ho provato accesso this.Keys e base.Keys e né opere all'interno MySubRow. Ho provato segnando la proprietà Keys come public in MyRow ma ho ottenuto "Il modificatore 'pubblico' non è valido per questo articolo", penso perché è necessario implementare un'interfaccia.

È stato utile?

Soluzione

Si sta implementando in modo esplicito la proprietà Keys. Se si vuole fare in quel membro accessibili al pubblico (o protected), cambiare IDictionary<string, string>.Keys a Keys e aggiungere il modificatore visibilità adeguata di fronte ad essa.

public ICollection<string> Keys { ... }

o

protected ICollection<string> Keys { ... }

Si potrebbe fare riferimento base come un esempio di IDictionary<string, string> così:

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

Ulteriori informazioni

(A giudicare dai vostri commenti in cui sembra avere familiarità con la distinzione, ma altri potrebbe non essere)

implementazione dell'interfaccia C # può essere fatto in due modi: implicitamente o esplicitamente. Consideriamo questa interfaccia:

public interface IMyInterface
{
    void Foo();
}

L'interfaccia è solo un contratto per ciò che i membri di una classe deve tenere a disposizione il codice che sta chiamando. In questo caso, abbiamo una funzione chiamata Foo che non accetta parametri e non restituisce nulla. Un'implementazione dell'interfaccia implicita significa che è necessario esporre un membro public che corrisponde al nome e la firma del membro sull'interfaccia, in questo modo:

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

Questo soddisfa l'interfaccia perché espone un membro public sulla classe che corrisponde ogni membro sull'interfaccia. Questo è ciò che di solito è fatto. Tuttavia, è possibile esplicitamente implementare l'interfaccia e mappare la funzione di interfaccia ad un membro private:

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

Questo crea una funzione privata sul MyClass che è accessibile solo per i chiamanti esterni quando si riferiscono a un'istanza di IMyInterface. Per esempio:

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

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

implementazioni espliciti sono sempre privato. Se si desidera esporre al di fuori della classe si dovrà creare un altro membro ed esporre che, quindi utilizzare l'implementazione esplicita di chiamare l'altro membro. Questo di solito è fatto in modo che una classe può implementare le interfacce senza ingombrare la sua API pubblica, o se due interfacce espongono i membri con lo stesso nome.

Altri suggerimenti

Dal momento che si sta implementando l'IDictionary interfaccia in modo esplicito, è necessario prima di lanciare this a IDictionary<string,string>:

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

Credo che sia Jared e Adam sono corretti: la proprietà è explitcity implementato sulla classe di base, con conseguente non essere pubblico. Si dovrebbe essere in grado di cambiare per un'implementazione implicita e renderlo felice:

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

protected permetterà ereditando classi per vederlo, ma nessun altra classe

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top