This might be bad practice, but I'd still like to know if it's possible.
public class BaseClass
{
protected virtual void createArrays(int vertexCount)
{
// do the actual work
}
}
public class A : BaseClass
{
protected override void createArrays(int vertexCount)
{
// Do something specific to A
base.createArrays(vertexCount);
}
}
public class B : A
{
protected override void createArrays(int vertexCount)
{
//Do something specific to B, but not to A
base.base.createArrays(vertexCount); // this is the part that doesn't work, I actually want to call the createArrays from the BaseClass
}
}
It's probably best to inherit both A and B from BaseClass, but I'd appreciate some insights
No, this is not allowed at all.
ECMA-334, the C# spec, says:
At binding-time, base_access expressions of the form
base.I
andbase[E]
are evaluated exactly as if they were written((B)this).I
and((B)this)[E]
, whereB
is the base class of the class or struct in which the construct occurs. Thus,base.I
andbase[E]
correspond tothis.I
andthis[E]
, exceptthis
is viewed as an instance of the base class.Note: Unlike
this
,base
is not an expression in itself. It is a keyword only used in the context of a base_access or a constructor_initializer (§15.11.2). end note
Having said that, a straight reading of ECMA-335, the .NET CLI spec, seems to imply that this would be allowed, by using a call
(as opposed to callvirt
) instruction on that method, as long as it's done as usual through an instance of the same type:
Partition III Section 3.19
When using the
call
opcode to call a non-final virtual method on an instance other than a boxed value type, verification checks that the instance reference to the method being called is the result ofldarg.s 0
,ldarg 0
orldarg.0
and the caller's body does not containstarg.s 0
,starg 0
orldarga.s 0
,ldarga 0
.[Rationale: This means that non-virtually calling a non-final virtual method is only verifiable in the case where the subclass methods calls one of its superclasses using the same
this
object reference, where same is easy to verify. This means that an override implementation effectively "hides" the superclass' implementation, and can assume that the override implementation cannot be bypassed by code outside the class hierarchy.For non-sealed class hierarchies, malicious code can attempt to extend the class hierarchy in an attempt to bypass a class' override implementation. However, this can only be done on an object of the malicious type, and not of the class with the override, which mitigates much of the security concern. end rationale]
I haven't tried it though, and it's possible that this would be considered non-verifiable code by most verifiers. It should at least work, as it's definitely correct (in the sense the IL will compile).