Tangible Software Solutions

The Most Trusted Name in Source Code Conversion

C++ Equivalent to C# Events

C++ (other than C++/CLI) does not have any syntax which is specific to events. C# has the event keyword which allows you to declare an event to which you can easily subscribe or unsubscribe multiple listeners in addition to letting all the listeners know when the event occurs. To do this in C++, you need to replace the event's delegate type with a std::function function pointer and replace the event declaration with a new field declaration using our generic 'TangibleEvent' helper class. The 'TangibleEvent' class takes care of two different listener collections and has methods for adding or removing an event subscription. Two different collections are necessary since C# allows subscribing to an event by specifying a method name or delegate instance(named listener) or subscribing by specifying a lambda.

Here's a simple example:

C#:

public class EventSource
{
    public delegate void FooDelegate();
    public event FooDelegate FooEvent;

    private void RaiseFooEvent()
    {
       FooEvent();
    }
}

public class EventClient
{
    public void SubscribeAndUnsubscribe()
    {
       EventSource t = new EventSource();
       //subscribe via method name:
       t.FooEvent += HandleFooEvent;
       //unsubscribe via method name:
       t.FooEvent -= HandleFooEvent;

       //subscribe via lambda:
       t.FooEvent += () =>
       {
          HandleFooEvent();
       };
    }

    private void HandleFooEvent()
    {
    }
}

C++:

#include "tangible_event.h"

class EventSource
{
    using FooDelegate = std::function<void ()>;
public:
    TangibleEvent<FooDelegate> *FooEvent = new TangibleEvent<FooDelegate>();

    void RaiseFooEvent()
    {
       //invoke all listeners:
       for (auto listener : FooEvent->listeners())
       {
          listener();
       }
    }
};

class EventClient
{
public:
    void SubscribeAndUnsubscribe()
    {
       EventSource *t = new EventSource();
       //subscribe via method name:
       t->FooEvent->addListener(L"HandleFooEvent", [&] () {HandleFooEvent();});
       //unsubscribe via method name:
       t->FooEvent->removeListener(L"HandleFooEvent");

       //subscribe via lambda:
       t->FooEvent->addListener([&] ()
       {
          HandleFooEvent();
       });
    }

private:
    void HandleFooEvent()
    {
    }
};

//"tangible_event.h" follows:
//----------------------------------------------------------------------------------------
// Copyright © 2007 - 2015 Tangible Software Solutions Inc.
// This class can be used by anyone provided that the copyright notice remains intact.
//
// This class is used to convert C# events to C++.
//----------------------------------------------------------------------------------------
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>

template<typename T>
class TangibleEvent final
{
private:
    std::unordered_map<std::wstring, T> namedListeners;
public:
    void addListener(const std::wstring &methodName, T namedEventHandlerMethod)
    {
       if (namedListeners.find(methodName) == namedListeners.end())
          namedListeners[methodName] = namedEventHandlerMethod;
    }
    void removeListener(const std::wstring &methodName)
    {
       if (namedListeners.find(methodName) != namedListeners.end())
          namedListeners.erase(methodName);
    }

private:
    std::vector<T> anonymousListeners;
public:
    void addListener(T unnamedEventHandlerMethod)
    {
       anonymousListeners.push_back(unnamedEventHandlerMethod);
    }

    std::vector<T> listeners()
    {
       std::vector<T> allListeners;
       for (auto listener : namedListeners)
       {
          allListeners.push_back(listener.second);
       }
       allListeners.insert(allListeners.end(), anonymousListeners.begin(), anonymousListeners.end());
       return allListeners;
    }
};

If you need to convert from C# to C++ and you are depending on the results being reliable and accurate, then you will want to have C# to C++ Converter, the best C# to C++ converter, at your fingertips.

Copyright © 1997 - 2017 Tangible Software Solutions Inc.