#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.
Комментариев нет:
Отправить комментарий