If you have tested both of:
class DoubleDown: IGeneric<Derived1>, IGeneric<Derived2> {
string IGeneric<Derived1>.GetName() {
return "Derived1";
}
string IGeneric<Derived2>.GetName() {
return "Derived2";
}
}
class DoubleDown: IGeneric<Derived2>, IGeneric<Derived1> {
string IGeneric<Derived1>.GetName() {
return "Derived1";
}
string IGeneric<Derived2>.GetName() {
return "Derived2";
}
}
You must have realized that the results in reality, changes with the order you declaring the interfaces to implement. But I'd say it is just unspecified.
First off, the specification(§13.4.4 Interface mapping) says:
- If more than one member matches, it is unspecified which member is the implementation of I.M.
- This situation can only occur if S 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.
Here we have two questions to consider:
Q1: Do your generic interfaces have different signatures?
A1: Yes. They are IGeneric<Derived2>
and IGeneric<Derived1>
.
Q2: Could the statement IGeneric<Base> b=x;
make their signatures identical with type arguments?
A2: No. You invoked the method through a generic covariant interface definition.
Thus your call meets the unspecified condition. But how could this happen?
Remember, whatever the interface you specified to refer the object of type DoubleDown
, it is always a DoubleDown
. That is, it always has these two GetName
method. The interface you specify to refer it, in fact, performs contract selection.
The following is the part of captured image from the real test
This image shows what would be returned with GetMembers
at runtime. In all cases you refer it, IGeneric<Derived1>
, IGeneric<Derived2>
or IGeneric<Base>
, are nothing different. The following two image shows more details:
As the images shown, these two generic derived interfaces have neither the same name nor another signatures/tokens make them identical.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…