3

Я не уверен, что происходит. У меня есть следующий базовый класс:Свойство C# недоступно в производном классе

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» не содержит определения для «Ключей». Оба класса находятся в пространстве имен MyNamespace. Я попытался получить доступ к this.Keys и base.Keys и не работает с MySubRow. Я пробовал маркировать свойство Keys как public в MyRow, но получил «Модификатор« public »недопустим для этого элемента», я думаю, потому что необходимо реализовать интерфейс.

ответ

7

Вы реализуете свойство Keys явно. Если вы хотите сделать этот участник общедоступным (или protected), измените IDictionary<string, string>.Keys на Keys и добавьте перед ним соответствующий модификатор видимости.

public ICollection<string> Keys { ... } 

или

protected ICollection<string> Keys { ... } 

Вы можете ссылаться на base как экземпляр IDictionary<string, string>, а также:

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

Дополнительная информация

(Судя по вашим комментариям вы, кажется, быть fami лже с отличием, но другие могут отсутствовать)

Реализация интерфейса 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 или если два интерфейса отображали члены с тем же именем.

+0

ОП обращается к члену, не пытается реализовать это – JaredPar

+0

@ Джаред: Посмотрите на свой первый класс. Свойство реализовано там, и это делается так явно. –

+0

@Adam, gotcha, пропустил явную реализацию – JaredPar

3

Поскольку вы реализации IDictionary < TKEY, интерфейс TValue > явно, вы должны сначала бросить this в IDictionary<string,string>:

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

Спасибо. Я закончил удаление явного описания интерфейса в 'MyRow'. Теперь это просто 'public ICollection Работает ключ и работает' base.Keys'. –

+0

@Sarah, в некоторых ситуациях вам придется использовать то, что предложил @dtb, потому что несколько интерфейсов будут определять одно и то же имя метода ... –

+0

@Rob: это на самом деле то, что я сделал в прошлом, а затем, в результате рефакторинг, уменьшенные интерфейсы, которые реализует класс, поэтому явная реализация больше не нужна. –

0

Я полагаю, что оба Джаред и Адам правильно: свойство explitcity реализуется на базовый класс, в результате чего он не является общедоступным. Вы должны быть в состоянии изменить его неявной реализации и сделать его счастливым:

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

Я сделал это неявным и «публичным», да. –

0

protected позволит наследовать классы, чтобы увидеть его, но ни один другой класс

+0

Это не проблема. Я не мог отметить его как «public» или «protected», потому что я явно реализовал интерфейс. При явном ее реализации добавление модификатора типа 'public' вызвало отдельную ошибку компиляции. Я закончил тем, что сделал его неявной реализацией, добавив «public»: 'public ICollection Keys'. –

Смежные вопросы