Inheriting base class events - c#

I do not know if there is an answer to this - I can not seem to find examples so maybe my terminology is not right or maybe this should not be done so forgive me for asking.
I have a base class with an object that has several events and event handling code - basically this is a boiler plate process using a FileSystemWatcher.
In my base I have all the code wired up for handling particular events and error handling.
The issue is that I am looking to be able to control what events of file system watcher the base class should subscribe to (was thinking to include all and use a switch case to add them) but then I need to handle them in the derived class and not in the base - because there is specific functionality of the derived classes that I want. I do not want to implement all the events in the base if possible - because I do not want the overhead when 4 to 8 of these derived classes are running. One thing I would like is force a derived class to SUBSCRIBE to an event.
I know from DCcoder that abstract was key in forcing methods to be 'must inherit' but I am at a loss on forcing the subscription.
public abstract class myBase
{
public event EventHandler<string> MessageAvailable;
protected void OnMessageAvailable(string e)
{
MessageAvailable?.Invoke(this, e);
}
public event EventHandler<Exception> Error;
protected virtual void OnError(Exception e)
{
Error?.Invoke(this, e);
}
}
public myderivedclass : myBase
{
this.Message += IfYouwantTo;
this.Error += REQUIRE_THIS_SUBSCRIPTION_HandleErrorHere;
}
DerivedClass needs to actually handle the events so do I create an empty event handler in the base class and use an interface to force my derived class to override the base or rather than that force the derived class to implement the handler ??
Or am I going about this all wrong ?
Any examples are appreciated ..

Related

C# Subscribing to Events Using Interfaces

I have recently started working with C# events and I am really liking the ease of use they offer (I come from a java background where we have to do all this event stuff manually).
However, there is one thing from my java background that I am missing: the inheritance side.
In java, if you want to subscribe to an event, you would inherit an interface such as IKeyListener. The interface would contain all of the method event signatures which you would then implement in the subscribing class. Whenever a key would be pressed, these implemented methods would be fired. Much the same as C#. However, unlike in java, I am unable to identify which classes subscribe to certain events because they don't actually inherit anything.
So if I wanted a list of objects which have key press event support I could do
List<IKeyListener> keyListeners = new ArrayList<IKeyListener>();
However, I don't see any good way to do this in C#. How would I be able to create list similar to the one above? Preferably without much "hackiness".
Thank you.
In C# you can define the event in an interface like this:
public interface IDrawingObject
{
event EventHandler ShapeChanged;
}
Then you can do what you want and store them like this:
var shapes = new List<IDrawingObject>();
A class can then implement the interface like this:
public class Shape : IDrawingObject
{
public event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something here before the event…
OnShapeChanged(new MyEventArgs(/*arguments*/));
// or do something here after the event.
}
protected virtual void OnShapeChanged(MyEventArgs e)
{
if(ShapeChanged != null)
{
ShapeChanged(this, e);
}
}
}
So in other words the event becomes part of the interface and if a class implements that interface, the class must provide an implementation for the event as well. That way you are safe to assume the implementing class has the event.
Finally every event will need to share some info about the event. That class can inherit the EventArgs class like below:
public class MyEventArgs : EventArgs
{
// class members
}

Where to subscribe to events of the inner object?

I'm often encountering a situation where I must decide where to subscribe to events of the inner object?
For example, I have an object model looks like this:
class ClassA
{
public event EventHandler SomeEvent1;
public event EventHandler SomeEvent2;
public event EventHandler SomeEvent3;
public event EventHandler SomeEvent4;
}
class ClassB
{
private ClassA a;
public ClassA A
{
get
{
return this.a;
}
}
public ClassB()
{
this.a = new ClassA();
// here subscribe to some events (for example, SomeEvent1 and SomeEvent2)
// this.a.SomeEvent1 += OnSomeEvent1Raised;
// this.a.SomeEvent2 += OnSomeEvent2Raised;
}
}
class ClassC
{
public ClassB B { get; }
}
class ClassD
{
public ClassC C { get; }
public void SomeMethod()
{
// Here subscribe to another ones events of object C.B.A. For example:
C.B.A.SomeEvent3 += OnSomeEvent3Raised;
C.B.A.SomeEvent4 += OnSomeEvent4Raised;
}
private void OnSomeEvent4Raised(object sender, EventArgs e)
{
throw new NotImplementedException();
}
private void OnSomeEvent3Raised(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
I've tried to create something like a UML diagram:
Structure of existing code of my project has places where such object model exist (its has a places where subscribing to events implemented as in the example above - C.B.A.SomeEvent+= ).
I don't like it and want to change it.
I want to here from you the best practices about this situation.
Alternative approach is to duplicate all events of classA in the classB, classC, classD.
And then replace all subscriptions to events to ONE PLACE (I mean that in the classB we will subscribe/unsubscribe to all events of the object of ClassA. In the classC we will subscribe/unsubscribe to all events of the object of classB. And so on...) In this case all subscriptions and unsubscriptions will be in one place. Hope, you understand what I mean here.
Again, please rely on your knowledge and experience tell we how to resolve this situation.
UPDATE
Do you agree with me that subscriptions and unsubscriptions to events must be placed in ONE PLACE ?
Please, answer on this additional question too.
Thanks in advance.
You might be interested in an event aggregator.
What it basically does is decoupling the publishers from subscribers - it's kind of a event container. You could get the event aggregator through dependency injection (e.g. MEF) for each class you'd like to subscribe or publish from.
The way I personally use and like it the most, is the way Rob Eisenberg implemented the event aggregator in Caliburn Micro:
NuGet Gallery
Caliburn.Micro Event Aggregator Documentation
In your case object A, B and C would share the same instance of an event aggregator, which means as soon as events are published on this event aggregator, all these objects recognize it. Class A, B and C are able behave differently, caused by different handling of certain events.
EDIT
The use of an event aggregator is, that you subscribe to the aggregator itself with an instance of a class. The connection between publisher and subscriber class happens through relying to the same instance of the event aggregator. In case of Caliburn.Micro subscription to certain events happens through implementing a generic interface (IHandle<>).
For example: if you'd like to subscribe to MyCustomEvent you implement the IHandle<MyCustomEvent> interface in the class to be subscribed.
This requires an implementation of the void Handle(MyCustomEvent e) method from the IHandle<MyCustomEvent> interface for this type of event. This method gets called everytime a (new) MyCustomEvent is published on the shared event aggregator.
There is way too much public stuff in your example. Hope I'll make sense below:
ClassB contains an object of type ClassA, and handles some ClassA events
ClassC contains an object of type ClassB but events are ignored.
ClassD contains an object of type ClassC and handles events from the ClassA object inside the ClassB object contains in this ClassC objects
#2 and #3 are not good: ClassC should handle and implement the events, handling them and letting them "bubble up" (invoking their own, same, event) for ClassD to handle correctly.
Basically, all of them should handle all events, either reacting to them (as in ClassB to ClassA's events) or just propagating them.
Find nice solution here:
Csharp-NotificationCenter

Add event handler in derived class' constructor or override the OnX() method?

When designing a derived class, are there [dis]advantages to adding a handler to a base class event in the ctor vs overriding the OnEventName() method and adding some behaviour (as well as calling the base method), if one doesn't need to change the base method and doesn't care in what order things happen, but only wants a reusable component with a little extra behaviour?
base class:
public abstract class BaseClass
{
public event EventHandler SomeEvent;
protected void OnSomeEvent(object sender, EventArgs e)
{
// do some stuff
}
}
option A:
public class DerivedA
{
protected override void OnSomeEvent(object sender, EventArgs e)
{
// do some other stuff
base.OnSomeEvent(sender, e);
}
}
option B:
public class DerivedB
{
public DerivedB()
{
SomeEvent += (o,e) => { // do some other stuff };
}
}
There aren't any significant advantages/disadvantages to either approach.
There's a few differences between subscribing to an event vs. overriding a base-class method. For example, if you want some code to run before or after all other handlers, you should really override the OnSomeEvent method, as there's no way to gaurantee that otherwise. But you indicate you don't really care about this.
In general, overriding a method is something that requires a good understanding of the behavior of the base class to ensure that you don't inadvertantly break anything. Subscribing to an event is a less intrusive extensions, and is something that (presumably) the base class designer has planned for.
Sometimes, people argue that performance is better when overriding - but I don't buy this argument. Performance only matters when it matters. The difference here is likely so negligible, that one should be more concerned with simplicity, correctness, and easy of maintenance over performance.
You've already mentioned the order in which things are called. Some other things which admittedly don't happen all that often, but might be significant (based on the fact that the base class controls how the event handlers are invoked):
Event handlers might be called on a different thread;
Under some circumstances, the base class might choose not to call event handlers at all;
The base class might catch specific types of exceptions thrown by handlers; exceptions thrown by your handler might be unintentionally swallowed.
In general, I tend to see events as being there exclusively for a class's users, with a well-designed class having virtual On... methods for subclasses.

Make sure base method gets called in C#

Can I somehow force a derived class to always call the overridden methods base?
public class BaseClass
{
public virtual void Update()
{
if(condition)
{
throw new Exception("..."); // Prevent derived method to be called
}
}
}
And then in a derived class :
public override void Update()
{
base.Update(); // Forced call
// Do any work
}
I've searched and found a suggestion to use a non-virtual Update() but also a protected virtual UpdateEx(). It just doesn't feel very neat, isn't there any better way?
I hope you get the question and I am sorry for any bad English.
Use the template method pattern - don't override the base method which needs to do some work, override one specific bit, which can either be abstract or a no-op in the base class. (The decision about whether to make it a no-op or abstract is usually fairly obvious - does the base class make sense on its own, as a concrete class?)
It sounds like this is basically the pattern you've found with UpdateEx - although it's usually UpdateImpl or something similar in my experience. There's nothing wrong with this as a pattern, in my view - it avoids any idea of forcing all derived classes to write the same code to call the base method.
This took me a bit to get what Update and UpdateEx would look like. Here's a code example that might help others.
public class BaseClass
{
// This is the Update that class instances will use, it's never overridden by a subclass
public void Update()
{
if(condition);
// etc... base class code that will always run
UpdateEx(); // ensure subclass Update() functionality is run
}
protected virtual void UpdateEx()
{
// does nothing unless sub-class overrides
}
}
A subclass will never have any implementation for Update(). It'll uses UpdateEx() to add implementation to Update();
public class ConcreteClass : BaseClass
{
protected override void UpdateEx()
{
// implementation to be added to the BaseClass Update();
}
}
Any instance of ConcreteClass will use the BaseClass implementation of Update() along with however ConcreteClass extends it with UpdateEx().
I think that the suggestion which you found is good.
The only base class method which you can't avoid calling from the subclass in base class constructor.
I think having a non-virtual base member that calls a virtual "hook" that can be extended is the most common solution for this kind of problem.
Depending on your use case, you might want to use an event instead, but the usual pattern for implementing an event is to have a virtual OnEvent method that subclasses can override instead of adding an event handler, so in your example case it boils down to the same thing.

Performing a common action on derived types

Is there a neat way to make several classes (which say derive from 1 interface), to each perform a same action? Think of http modules in ASP.NET which serve each request (Each the key word) - is there a way to perform some common action on derived types? Reflection may be one way, though I would be interested in a way at a base class level.
Thanks
Not with only an interface; you'd want an abstract class in the middle there:
abstract class Whatever : IFooable {
public virtual void Do () {
PreDo();
}
protected abstract void PreDo();
}
Then you call Do, and PreDo is automatically called first on all implementing types.
(Edit: Just to be clear, I made Do virtual so this means if you re-implement it you should call base.Do() as the first thing, just to ensure that it actually calls the parent method).
If your classes all derive from a common base class, you could put this logic in your common base class.
If I understand what you are asking correctly, then perhaps an event handler is the way to go?
If you need a bunch of objects to respond to some action, then events (also called "message passing") is the way to go.
Something like this?
class Foo
{
public event EventHandler PerformAction;
private void OnActionNeeded()
{
// A bunch of Bars need to do something important now.
if (PerformAction != null)
PerformAction.Invoke();
}
}
class Bar
{
public Bar(Foo fooToWatch)
{
fooToWatch.PerformAction += new EventHandler(Foo_PerformAction);
}
void Foo_PerformAction(object sender, EventArgs e)
{
// Do that voodoo that you do here.
}
}
May not be a complete answer but I am tempted to think in terms of AOP and attributes.
some references:
http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx
http://www.postsharp.org/contributions/documentation/removing-duplicate-code-in-functions
The Template Method design pattern may apply to what you're asking.
http://www.dofactory.com/Patterns/PatternTemplate.aspx
The overall point of designing an interface is to provide a protocol between two components and hide the implementation part.
The interfaces serve as a communication medium.
And what you are asking seem to be specific to implementaion.
Which can be cleanly handled using utility classes(singleton with the method)
I do not suggest to have abstract class in ur current scenario.

Categories

Resources