I think this question is best understood by an example so here we go:
public class Base {
// this method works fine
public void MethodA(dynamic input) {
// handle input
}
}
public class Derived: Base { // Derived was named Super in my original post
// This is also fine
public void MethodB(dynamic input) {
MethodA(input);
}
// This method does not compile and the compiler says:
// The call to method 'MethodA' needs to be dynamically dispatched,
// but cannot be because it is part of a base access expression.
// Consider casting the dynamic arguments or eliminating the base access.
public void MethodC(dynamic input) {
base.MethodA(input);
}
}
The compiler clearly states that method C is invalid due to the fact that it is using base access to call method A. But why is that?
And how does one call the base method when overriding a method with dynamic parameters?
E.g. what if I wanted to do:
public class Base {
// this method works fine
public virtual void MethodA(dynamic input) {
Console.WriteLine(input.say);
}
}
public class Derived: Base { // Derived was named Super in my original post
// this does not compile
public override void MethodA(dynamic input) {
//apply some filter on input
base.MethodA(input);
}
}
Yes, this cannot work by design. The base.MethodA() call makes a non-virtual call to a virtual method. The compiler has little trouble emitting the IL for this in the non-dynamic case since it knows what specific method needs to be called.
That's not the case for dynamic dispatch. It is the job of the DLR to figure out which specific method needs to be called. What it has to work with is the MethodTable of the Derived class. That table does not contain the address of the base class' MethodA method. It was overwritten by the override. All it can possibly do is call the Derived.MethodA() method. Which violates the base keyword contract.
In your example, Derived
doesn't have a method named MethodA
, so calling base.MethodA()
is the same as calling this.MethodA()
, so you can just call the method directly and be done with it. But I am assuming you also have a different this.MethodA()
and you want to be able to call base.MethodA()
. In this case, just listen to the compiler's advice and cast the argument to object
(remember that dynamic
is really just object
that the compiler treats in a special way):
base.MethodA((object)input);
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