Pergunta

Não tenho certeza do que está acontecendo.Eu tenho a seguinte classe 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 então eu tenho esta classe derivada:

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

Por que recebo esse erro?"'MyNamespace.MyRow' não contém uma definição para 'Keys'".Ambas as turmas estão no MyNamespace espaço para nome.Eu tentei acessar this.Keys e base.Keys e nenhum dos dois funciona por dentro MySubRow.Eu tentei marcar o Keys propriedade como public em MyRow mas obtive "O modificador 'público' não é válido para este item", acho que é necessário implementar uma interface.

Foi útil?

Solução

Você está implementando o Keys propriedade explicitamente. Se você deseja tornar esse membro acessível publicamente (ou protected), mudança IDictionary<string, string>.Keys para Keys e adicione o modificador de visibilidade apropriado na frente dele.

public ICollection<string> Keys { ... }

ou

protected ICollection<string> Keys { ... }

Você pode fazer referência base Como uma instância de IDictionary<string, string> também:

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

Mais Informações

(A julgar pelos seus comentários, você parece estar familiarizado com a distinção, mas outros podem não ser)

A implementação da interface C# pode ser feita de duas maneiras: implicitamente ou explicitamente. Vamos considerar esta interface:

public interface IMyInterface
{
    void Foo();
}

Uma interface é apenas um contrato para o que os membros uma classe deve disponibilizar para o código que está chamando. Nesse caso, temos uma função chamada Foo Isso não leva parâmetros e não retorna nada. Uma implementação implícita de interface significa que você deve expor um public Membro que corresponde ao nome e assinatura do membro na interface, assim:

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

Isso satisfaz a interface porque expõe um public Membro da classe que corresponde a todos os membros na interface. Isso é o que geralmente é feito. No entanto, é possível explicitamente implementar a interface e mapear a função de interface para um private membro:

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

Isso cria uma função privada em MyClass isso só é acessível a chamadores externos quando eles estão se referindo a uma instância de IMyInterface. Por exemplo:

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

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

Implementações explícitas são sempre privado. Se você deseja expor -o fora da classe, terá que criar outro membro e expor isso, use a implementação explícita para ligar para o outro membro. Isso geralmente é feito para que uma classe possa implementar interfaces sem atravessar sua API pública ou se duas interfaces expõem os membros com o mesmo nome.

Outras dicas

Como você está implementando explicitamente a interface IDictionary<TKey,TValue>, primeiro você precisa converter this para IDictionary<string,string>:

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

Acredito que Jared e Adam estão corretos: a propriedade é explicada na classe base, resultando em não ser pública. Você deve ser capaz de alterá -lo para uma implementação implícita e torná -lo feliz:

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

protected permitirá que as aulas de herdador o vejam, mas nenhuma outra classe

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top