Dynamic dispatch to derived class in C# - c#

I'm trying to do the following:
public abstract BaseClass {
public virtual void ReceiveEvent(Event evt)
{
ProcessEvent(evt as dynamic);
}
private void ProcessEvent(object evt)
{
LogManager.Log(#"Received an event that is not being processed!
Dispatch fallback");
}
}
public DerivedClass: BaseClass {
private void ProcessEvent(SpecificEvent evt)
{
LogManager.Log("Processing Event");
}
}
SpecificEvents hit the fallback method instead of the one in the derived class. I use dynamic dispatch within the same class all the time and find it really useful/clean. Will it not work with derived classes as illustrated in the example above?
EDIT:
There seems to be some confusion in the answers. Basically i use the following design all the time:
public class SomeClass{
public void DoSomethingDispatcher(SomeObject obj)
{
ProcessObject(obj as dynamic);
}
private void DoSomething(SomeObjectType1 obj)
{
}
private void DoSomething(SomeObjectType2 obj)
{
}
private void DoSomething(SomeObjectType3 obj)
{
}
private void DoSomething(object obj) //fallback
{
}
}
Works great for when you don't know the exact type beforehand and you don't want to use a big switch statement. Just wondering if this can be implemented with inheritance where the base class holds the fallback method and the derived class holds all the more specific methods.

It's not working for you because even if evt is passed dynamic, ProcessEvent is not declared as virtual. This means that when the call to ProcessEvent is compiled, it is linked to the only implementation of the method that is found in the base class, and the ones in the derived classes will never be executed. Furthermore, you can't simply declare your ProcessEvent as virtual, since the signature will be different in the derived classes.
In order for your code to work as expected you could just override ReceiveEvent in the derived classes leaving it exactly the same:
public override void ReceiveEvent(Event evt)
{
ProcessEvent(evt as dynamic);
}
If you want to manage the unhandled events in the base class, just change the modifier of Process event in the base class to protected (otherwise it can't be executed when called by the overridden version of ReceiveEvents).

If the method is not virtual/abstract in the base class, and the method is not marked as override in the derived class, it will never work.
Also, I dont understand the usage of dynamic here.

What is the type of your "evt" when it hit ProcessEvent ?
You may take a look to Using Type dynamic :
The type is a static type, but an object of type dynamic bypasses
static type checking. In most cases, it functions like it has type
object.
So, evt is not a SpecificEvent.

To get the expected behaviour you should override the virtual method:
public DerivedClass: BaseClass
{
private override void ReceiveEvent(Event evt)
{
// Process your event here.
}
}
With this code, ReceiveEvent in the base class won't be called, thus the fallback ProcessEvent won't be called.
There is no reason to use dynamic.

Related

Order of execution in Abstract Class

I came across a posting where it is said that MustBeCalled() method will get called if we have the Abstract class do the calling in this manner.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
But how does MustBeCalled() method get called?
In what order things are called here?
If you call PerformFunction() first, then everything will execute in the intended order, where that order is specified in the order of the lines of code in PerformFunction(). If you call AbstractMethod() directly, there's no guarantee that MustBeCalled() will ever be called. However, I notice that you have AbstractMethod() marked as protected, which means that outside consumers of your class will not be able to call it directly. They'll have to use PerformFunction() -- this is good, as there is now only one public way to invoke your internal methods, and that way guarantees the order that you need.
In truth, there is a level at which you can only guarantee that things happen by choosing to write code to make them happen. You can't, for example, guarantee that code is going to implement a game of Tetris except by actually writing that code and choosing to implement it in such a way that it produces Tetris behavior. The type system and the public/protected/private modifiers can help some by preventing some misuse (as your internals are not accessible and thus cannot be invoked by consumers of your module), but they can only go so far. This is such a case.
You cannot enforce how an implementation to call a method when invoked. The implementation could do its own thing entirely, or do nothing.
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
// this is a perfectly valid implementation
}
}
A better implementation could be.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
private void MustBeCalled()
{
}
protected virtual void AbstractMethod()
{
MustBeCalled();
}
}
This way refactoring tools will at least create the desired boilerplate code:
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
base.AbstractMethod();
}
}
However, the person overriding AbstractMethod still needs to call base.AbstractMethod, this is not enforced by the compiler at all.

How to tell if MemberInfo represents an override

Given the following code:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public override void Method() { }
}
...
var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];
Is it possible to determine if the derivedMethodInfo represents a method declaration which overrides another in a base class?
In another question it was observed that had Method been declared abstract (and not implemented) in the base class, derivedMethodInfo.DeclaringType would have turned up as Base, which makes sense after reading #EricLippert's comments. I noticed that in the present example, since the derived class re-declares the method, that derivedMethodInfo.DeclaringType == derivedMethodInfo.ReflectedType, viz. Derived.
There doesn't seem to be any connection between baseMethodInfo and derivedMethodInfo, other than their names are the same and their respective declaring types appear in the same inheritance chain. Is there any better way to make the connection?
The reason I ask is that there appears to be no way to distinguish, through reflection, between the earlier example and the following one:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public new void Method() { }
}
In this case as well, the Derived class both declares and reflects a member called Method.
A method shadowing a virtual method will have the VtableLayoutMask flag set in Attributes.
Note that an ordinary virtual method (with no similar name from a base type) will also have this flag set.
This flag appears to indicate that the method introduces a new entry in the VTable.
There's a more specific class MethodInfo which derives from MemberInfo. Note that not all kinds of members can be virtual (fields cannot, for example).
If you say
var derivedMethodInfo = typeof(Derived).GetMethod("Method");
then you can check if
derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo
or not. See documentation for GetBaseDefinition() where they also have a code example.

C# Overriding abstract methods (include input parameters)

It is possible in C# do something like this
public absctract class ImportBase()
{
public abstract void CreateDocument();
}
public class UsingOne : ImportBase
{
public override bool CreateDocument(string name)
{
return null;
}
}
I want have some Base class, which only have some methods,but in derived class i need change inputs parameters and inside of method.
You're not overriding the method. The point of having an abstract (or virtual) method is that given any ImportBase, I should be able to call
importBase.CreateDocument();
That's clearly not the case with UsingOne, as it needs more information. So you're really trying to tie your caller to UsingOne, not just ImportBase - at which point you've lost the benefits of polymorphism.
To override a method, the implementation has to have the same signature, basically.
Probably you want to minimize the duplicate code on your derived classes. Basically it's not possible to have an override of a different signature but surely you can refactor your code where you can keep the possible duplicate code in the base class and use it on your derived classes.
public absctract class ImportBase()
{
//Making this protected here
protected virtual void CreateDocument()
{
//Your CreateDocument code
};
}
public class UsingOne : ImportBase
{
private override void CreateDocument()
{
// Override this if you have different CreateDocument for your different
// for different derived class.
}
public bool CreateDocument(string name)
{
// Do whatever you need to do with name parameter.
base.CreateDocument();
// Do whatever you need to do with name parameter.
return true; // return false;
}
}
You can create instance of UsingOne and invoke CreateDocument(string name)
nope. signature must be same on the derived class. i suggest to use builder pattern.
http://en.wikipedia.org/wiki/Builder_pattern

Force base method call

Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper

What's the difference between an abstract class, and a class with only protected constructors? (.NET)

What are all the difference between an abstract class, and a class with only protected constructor(s)? They seem to be pretty similar to me, in that you can't instantiate either one.
EDIT:
How would you create an instance in a derived class, with a base class with a protected constructor? For instance:
public class ProtectedConstructor
{
protected ProtectedConstructor()
{
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor(); // this is fine
}
}
public class DerivedClass : ProtectedConstructor
{
public void createInstance()
{
ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
}
public static ProtectedConstructor getInstance()
{
return new ProtectedConstructor(); // doesn't compile
}
}
You can instantiate a class with protected constructors from within the class itself - in a static constructor or static method. This can be used to implement a singleton, or a factory-type thing.
An abstract class cannot be instantiated at all - the intent is that one or more child classes will complete the implementation, and those classes will get instantiated
Edit:
if you call ProtectedConstructor.GetInstance(); instead of new ProtectedConstructor();, it works. Maybe protected constructors can't be called this way? But protected methods certainly can.
Here is an interesting article on the topic.
Most of the time, there is little practical difference, as both are only able to be generated via a subclass.
However, marking a class abstract has two benefits:
With protected constructors, it's still possible to create an instance of the class in two ways. You can use Activator.CreateInstance with BindingFlags.NonPublic, or you can use a factory method defined in the class (or a subclass) to create an instance of the class. A class marked abstract, however, cannot be created.
You are making your intention more clear by marking the class abstract. Personally, I find this the most compelling reason to do so.
From an outside , black-box perspective, yes they are similar in that you cannot instantiate either one. However, you can never instantiate an abstract class, where you can construct a class with only protected constructors from within the class itself, or from an inheritor.
An abstract class can have abstract methods; methods that consist only of the method signature, but no body, that child classes must implement.
Seriously, not one person mentioned that yet?
Your example is flawed because in the getInstance case because you construct a ProtectedConstructor class and expect to down cast it as a DerivedClass. Instead you need a slightly more complete implementation where the derived class has a constrcutor:
public class ProtectedConstructor
{
protected ProtectedConstructor(string arg)
{
// do something with arg
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor("test");
}
}
public class DerivedClass : ProtectedConstructor
{
protected DerivedClass(string arg) : base(arg)
{
}
public void createInstance()
{
DerivedClass p = new DerivedClass("test");
}
public static DerivedClass getInstance()
{
return new DerivedClass("test");
}
}
Regardless the major difference usage of abstract classes is to define abstract methods that subclasses must implement but you don't want to provide a default implementation for. For example suppose you have some kind of Thread class that has a Run method. You want to ensure that every call to Run first setups up some logging then does the real work of the thread and then stops logging. You could write an abstract Thread class like this:
public abstract Thread
{
protected Thread()
{
}
public void Run()
{
LogStart();
DoRun();
LogEnd();
}
protected abstract DoRun();
private void LogStart()
{
Console.Write("Starting Thread Run");
}
private void LogEnd()
{
Console.Write("Ending Thread Run");
}
}
public class HelloWorldThread : Thread
{
public HelloWorldThread()
{
}
protected override DoRun()
{
Console.Write("Hello World");
}
}
Another thing to consider, that I didn't see other people mention, is that your code may be maintained in the future. If the maintainer adds a public constructor to a class, then it can be instantiated. This might break your design, so you should prevent it (or design to accommodate it).
To prevent other people from making these kinds of changes, you can comment your code. Or, as other people said, use "abstract" to explicitly document your intent.
Well, the first difference that comes to mind is that an abstract class can not be instantiated, but a class with protected constructors could be instantiated throw another public method.
A common example of this might be something like the Singleton pattern: http://en.wikipedia.org/wiki/Singleton_pattern
if you inherit an abstract class from another abstract class, you do not have to satisfy abstract methods, but you do with a normal class with protected ctors. Examples
public abstract class Parent
{
protected abstract void AMethod();
}
public abstract class Child: Parent
{
// does not implement AMethod, and that's ok
}
public class Child2: Parent
{
// does not implement AMethod, and that will cause a compile error
}
If your intent is to only allow static uses of the class (i.e. not to use it as a pure base class) then you should use the static keyword instead; the CLR will prevent instances of the class being created via any method including Reflection (AFAIK).

Categories

Resources