Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Проблема с наследованием интерфейсов

#c_sharp #net #language_lawyer


Почему при компиляции этого:

using System;

public class Test
{
  public static void Main()
  {
    Lol l = new Lol();
    Console.WriteLine(((IParent)l).Family);
    Console.WriteLine(((IChild)l).Family);
    Console.WriteLine(l.Name);
  }
}

public interface IParent
{
  string Family { get; }
}

public interface IChild : IParent
{
  string Name { get; }
}

public class Lol : IChild
{
  string IParent.Family { get { return "suck"; } }
  string IChild.Family { get { return "duck"; } }
  public string Name { get { return "ross"; } }
}


IdeOne выдает это:

prog.cs(27,26): error CS0550: Lol.IChild.Family.get is an accessor not found in interface
member IChild.Family
Compilation failed: 1 error(s), 0 warnings
    


Ответы

Ответ 1



Дело в том, что у класса может быть лишь одна имплементация метода/свойства интерфейса. Интерфейс — лишь «обещание» имплементировать те или иные методы/свойства, а наследованный интерфейс — лишь более сильное обещание. У вас объявление class Lol : IChild есть обещание имплементировать все методы/свойства интерфейса IChild (то есть, в вашем случае, Name), а также все методы/свойства родительского интерфейса IParent. Свойство Family интерфейса IChild унаследовано от интерфейса IParent, таким образом в интерфейса IChild содержится не два, а только одно свойство Family. Разрешение имплементировать как IParent.Family, так и IChild.Family, привело бы к двум различным имплементациям одного и того же свойства. При этом компилятор не знал бы, какое из них использовать. Поэтому строчка string IChild.Family { get { return "duck"; } } не пропускается компилятором. Формально, запрещение можно найти в спецификации языка (которая находится в каталоге <тут каталог Visual Studio>\VC#\Specifications\1033\CSharp Language Specification.docx), в разделе 13.4.1 Explicit interface member implementations. Там разобран именно ваш случай: The fully qualified name of an interface member must reference the interface in which the member was declared. Thus, in the declarations interface IControl { void Paint(); } interface ITextBox: IControl { void SetText(string text); } class TextBox: ITextBox { void IControl.Paint() {...} void ITextBox.SetText(string text) {...} } the explicit interface member implementation of Paint must be written as IControl.Paint.

Комментариев нет:

Отправить комментарий