Imagine these specifications are from an external dll. A class that implements an interface explicitly:
public interface IDebug
{
string GetImportantInfo();
}
public class ExternalClass : IDebug
{
public void DoSomethingImportant()
{
System.Diagnostics.Debug.WriteLine("Something important was done...");
}
string IDebug.GetImportantInfo() //Explicit implementation
{
DoSomethingImportant();
return nameof(ExternalClass);
}
}
Then this one is from internal code, where you know you need to implement the interface:
public class Debug : ExternalClass, IDebug
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
Now when I'm calling the Debug
's GetImportantInfo()
method from the subclass, the explicit implementation in the superclass is not called:
static void Main(string[] args)
{
IDebug test = new Debug();
var impInfo = test.GetImportantInfo();
System.Diagnostics.Debug.WriteLine(impInfo); //"Debug"
}
And the only slight hint I seem to get is that I don't get a compile error when adding the IDebug
interface to the Debug
class, without implementing the method:
public class Debug : ExternalClass, IDebug
{
}
Why is there no compile warning when you overwrite a superclass's implementation like this? If the base class implements it implicitly, I get a compile warning telling me to use the new
keyword. But using the new
keyword to overwrite an explicitly implemented method gives a compile warning:
The member 'Program.Debug.GetImportantInfo()' does not hide an inherited member. The new keyword is not required.
Is there an intended purpose for this, or is this a bug? If it's intended, what is the official reasoning?
The problem here is that you are using a little known feature of the language: interface re-implementation:
public class Debug : ExternalClass, IDebug
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
Why are you redeclaring that Debug
implements IDebug
if ExternalClass
already does? You are re-implementationing the interface, and becuase you are doing such thing, you get no warning; the compiler assumes you know what you are doing.
If you want the behavior you seem to want, simply don't re-implement the interface:
public class Debug : ExternalClass
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
If the base class implements it implicitly, I get a compile warning telling me to use the new keyword.
This warning has nothing to do with interface implementation. The warning is simply due to method hiding, you have two methods with the same signature; IDebug
is a non factor here, you could put it out of the equation and you'd still get the same warning.
In my colleague's case, he said he had to implement both the base class and the interface because it was an event-based interface.
Well, then tell your colleague to figure out what he wants. If you reimplement the interface, then any call to DoSomething
, be it through a Debug
typed reference or an IDebug
typed reference, should call the reimplemented behavior. Any other behavior would be unexpected and deeply bewildering.
On the other hand, if you need to keep the orignal behavior of the base class if calling DoSomething()
through a IDebug
typed reference then do not re-implement the interface. What other alternative are you proposing?
Does this mean that you should know about what interfaces the base class implements? Well yes, of course. I find your question about why should anyone know what interfaces any given class you are going to inherit from implements deeply worrisome to be honest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With