How do you reorganize two classes with identical duplicate events?

Both of these classes contain another private class that raises events. The two classes then re-raise these events to clients.

Unfortunately, each of the two classes has the same code:

public class FirstClass { public delegate void FooEventHandler(string foo); public delegate void BarEventHandler(string bar); public delegate void BazEventHandler(string baz); public event FooEventHandler Foo; public event BarEventHandler Bar; public event BazEventHandler Baz; private PrivateObject privateObject; public FirstClass() { privateObject.Foo += FirstClass_Foo; privateObject.Bar += FirstClass_Bar; privateObject.Baz += FirstClass_Baz; } private void FirstClass_Foo(string foo) { if (Foo != null) { Foo(foo); } } private void FirstClass_Bar(string bar) { if (Bar != null) { Bar(bar); } } private void FirstClass_Baz(string baz) { if (Baz != null) { Baz(baz); } } } 

As you can see, I need to re-create events from a private object. This is redundant. I tried using inheritance and put this repeating code in a base class, but I keep getting errors, like this:

The event "BaseClass.Foo" can be displayed only on the left side of + = or - = (except when it is used inside the type)

Does anyone know how to get rid of this duplicate code?

+6
source share
2 answers

how to expose private object events as properties of your shell? As in,

 public class ExternalClass { private InternalClass _internalObject = new InternalClass(); public event InternalClass.someDelegate SomeEvent { add { _internalObject.SomeEvent += value; } remove { _internalObject.SomeEvent -= value; } } } public class InternalClass { public delegate void someDelegate(string input); public event someDelegate SomeEvent; } 

If you are familiar with C # Properties, you probably already know the get and set keywords. The add / remove keywords are basically the same, only they start when you try to add or remove a value for your property.

So, when you command (un) to register your delegate on ExternalClass.SomeEvent , you actually (un) register in the InternalClass.SomeEvent event.

If you are not familiar with C # Properties, http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx will help you.

+5
source

I think this will work for you. An open interface allows PrivateObject to remain internal. The only trick is that RegisterIFooEvents should be called in the constructor.

 public interface IFooEvents { event BaseClass.FooEventHandler Foo; event BaseClass.BarEventHandler Bar; event BaseClass.BazEventHandler Baz; } internal class PrivateObject : IFooEvents { public event BaseClass.FooEventHandler Foo; public event BaseClass.BarEventHandler Bar; public event BaseClass.BazEventHandler Baz; public void ChangeFoo(string foo) { if (Foo != null) { Foo(foo); } } } public abstract class BaseClass : IFooEvents { public delegate void BarEventHandler(string bar); public delegate void BazEventHandler(string baz); public delegate void FooEventHandler(string foo); private IFooEvents _fooEvents; public event FooEventHandler Foo { add { _fooEvents.Foo += value; } remove { _fooEvents.Foo -= value; } } public event BarEventHandler Bar { add { _fooEvents.Bar += value; } remove { _fooEvents.Bar -= value; } } public event BazEventHandler Baz { add { _fooEvents.Baz += value; } remove { _fooEvents.Baz -= value; } } protected void RegisterIFooEvents(IFooEvents fooEvents) { _fooEvents = fooEvents; } } public class FirstClass : BaseClass { private readonly PrivateObject _privateObject; public FirstClass() { _privateObject = new PrivateObject(); RegisterIFooEvents(_privateObject); } public void ChangeFoo(string foo) { _privateObject.ChangeFoo(foo); } } 

Testing in a console application:

 class Program { static void Main(string[] args) { var class1 = new FirstClass(); class1.Foo += EventRaised; class1.ChangeFoo("TEST"); } static void EventRaised(string arg) { Console.WriteLine(arg); } } 
0
source

Source: https://habr.com/ru/post/897977/


All Articles