interface IBase { string Name { get; } } class Base : IBase { public Base() => this.Name = "Base"; public string Name { get; } } class Derived : Base//, IBase { public Derived() => this.Name = "Derived"; public new string Name { get; } } class Program { static void Main(string[] args) { IBase o = new Derived(); Console.WriteLine(o.Name); } }
In this case output will be "Base".
If I explicitly state that Derived implements IBase (which is in fact already implemented by base class Base and such annotation seem to be useless) the output will be "Derived"
class Derived : Base, IBase { public Derived() => this.Name = "Derived"; public new string Name { get; } }
What's the reason for such behavior?
VS 15.3.5, C# 7
No, you cannot access any derived class members using base class pointer even pointing to a derived class instance. However you can access those values though methods of derived class.
An interface is not a class. It contains only method signatures. It has no implementation on its own and cannot be instantiated. Its implementation logic is provided by the classes that derived from it.
1. A base class is an existing class from which the other classes are derived and inherit the methods and properties. A derived class is a class that is constructed from a base class or an existing class.
An interface defines how other classes can use your code. A base class helps implementers to implement your interface.
It's explained in sections 13.4.4 to 13.4.6 of the C# 5 specification. The relevant sections are quoted below, but basically if you explicitly state that a class implements an interface, that triggers interface mapping again, so the compiler takes that class as the one to use to work out which implementation each interface member is mapped to.
13.4.4 Interface mapping
A class or struct must provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.
Interface mapping for a class or struct
C
locates an implementation for each member of each interface specified in the base class list ofC
. The implementation of a particular interface memberI.M
, whereI
is the interface in which the memberM
is declared, is determined by examining each class or structS
, starting withC
and repeating for each successive base class ofC
, until a match is located:
- If
S
contains a declaration of an explicit interface member implementation that matchesI
andM
, then this member is the implementation ofI.M
.- Otherwise, if
S
contains a declaration of a non-static public member that matches M, then this member is the implementation ofI.M
. If more than one member matches, it is unspecified which member is the implementation ofI.M
. This situation can only occur ifS
is a constructed type where the two members as declared in the generic type have different signatures, but the type arguments make their signatures identical....
13.4.5 Interface implementation inheritance
A class inherits all interface implementations provided by its base classes. Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. For example, in the declarations
interface IControl { void Paint(); } class Control: IControl { public void Paint() {...} } class TextBox: Control { new public void Paint() {...} }
the
Paint
method inTextBox
hides thePaint
method inControl
, but it does not alter the mapping ofControl.Paint
ontoIControl.Paint
, and calls toPaint
through class instances and interface instances will have the following effectsControl c = new Control(); TextBox t = new TextBox(); IControl ic = c; IControl it = t; c.Paint(); // invokes Control.Paint(); t.Paint(); // invokes TextBox.Paint(); ic.Paint(); // invokes Control.Paint(); it.Paint(); // invokes Control.Paint();
...
13.4.6 Interface reimplementation
A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.
A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. For example, in the declarations
interface IControl { void Paint(); } class Control: IControl { void IControl.Paint() {...} } class MyControl: Control, IControl { public void Paint() {} }
the fact that
Control
mapsIControl.Paint
ontoControl.IControl.Paint
doesn’t affect the re-implementation inMyControl
, which mapsIControl.Paint
ontoMyControl.Paint
.
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