Нашел недавно забавный трюк.
Иногда при реализации интерфейса удобно какой-либо из объявленных членов реализовать производным типом. Как-то так.
private interface I { object P { get; } } private class C : I { public string P { get { return "Hello world!"; } } }
Но напрямую, в лоб, сделать этого нельзя: сигнатуры членов класса и интерфейса получаются разными, и интерфейс очень обижается, не признавая такую реализацию, несмотря на то, что string прекрасно приводится к object.
Program.cs(12,17): error CS0738: 'Test1.Program.C' does not implement interface member 'Test1.Program.I.P'. 'Test1.Program.C.P' cannot implement 'Test1.Program.I.P' because it does not have the matching return type of 'object'. Program.cs(9,11): (Related location) Program.cs(14,18): (Related location)
Однако, выход есть: интерфейс будет удовлетворен, если создать для него явную реализацию. Например, так:
private interface I { object P { get; } } private class C : I { public string P { get { return "Hello world!"; } } object I.P { get { return this.P; } } }
Правда, я совершенно не понимаю, откуда взялось ограничение, не позволяющее производному классу замещать базовый в этом контексте; более того, я без понятия, какими словами это гуглить. В msdn я ничего не нашел, лишь только аксиоматическое: жизнь несправедлива …член класса… …должен обладать таким же именем и сигнатурой, как член интерфейса, смирись с этим. Более того, я не совсем уверен, что у этого поведения есть цель, а не причина. В любом случае, если кто-нибудь знает причину, цель или кого-нибудь, кому уместно задать такой вопрос — черкните, пожалуйста, пару слов в комментариях.