-1
\$\begingroup\$

I am very green when it comes to working with events in C#, so I had come up with a custom example console application to familiarize myself with the syntax of them. I have this example working in its first draft state, but one of the issues I would like to resolve, is that in order to wire up to this event here:

internal class EventsExample
{
    internal delegate void DamageRollRolled(decimal damageRoll);
    internal event DamageRollRolled OnDamageRoll;
}

I need to pass the entire EventsExample class into the class that wants to subscribe to that event:

public class Proc
{
    public Proc(EventsExample example)
    {
        _example.OnDamageRoll += TryToProc;
    }
}

This seems like a very poor implementation overall, but I haven't quite figured out or managed to find an example I could understand for how to make something like this possible when creating an instance of Proc:

var example = new EventsExample();
var proc = new Proc(example.OnDamageRoll);

The examples I did find on how to possible solve issues like this point to creating a custom Event class, such as:

public class DamageRollRolledEvent
{
    public decimal DamageRoll;
}

But that alone doesn't really change the situation, even after creating a field in EventsExample of this type: internal DamageRollRolledEvent DamageRoll = new DamageRollRolledEvent();

Because I am not able to trigger the event with .Invoke() with this approach.

I feel like I'm missing something here that will help this all fall into place.

\$\endgroup\$

closed as off-topic by t3chb0t, Vogel612, alecxe, Graipher, Mast Nov 12 '17 at 20:15

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – t3chb0t, Vogel612, alecxe, Graipher, Mast
If this question can be reworded to fit the rules in the help center, please edit the question.

1
\$\begingroup\$

One way to solve this issue is to take inspiration from the same design pattern that c# uses for events:

  1. Create an Interface called IDamageRolledHandler which exposes a method matching the firm of the delegate:

    public interface IDamageRolledHandler
    {
        void TryToProc(decimal damageRoll);
    }
    
  2. Implement the interface in your Proc class:

    public class Proc : IDamageRolledHanler
    {
        public void TryProc(decimal damageRoll)
        {
            //Do something
        }
    }
    
  3. Finally, add subscription methods to your event class so you can manage the subscription without exposing your delegate

    internal class EventsExample
    {
        internal delegate void DamageRollRolled(decimal damageRoll);
        internal event DamageRollRolled OnDamageRoll;
    
        public void Subscribe(IDamageRolledHandler handler)
        {
            OnDamageRoll += handler.TryProc;
        }
    
        public void Unsubscribe(IDamageRolledHandler handler)
        {
            OnDamageRoll -= handler.TryProc;
        }
    
        public void OnDamageRolled(decimal damageRoll)
        {
            OnDamageRoll?.Invoke(damageRoll);
        }
    }
    

Now you get to execute to invoke your event:

public static void Main(string[] args)
{
    var proc = new Proc();
    var example = new EventsExample();
    example.Subscribe(proc);
    example.OnDamageRolled(10d);
    example.Unsubscribe(proc);
}

This implementation works great because it lets you abstract your event handling logic from the actual delegate while also encapsulating your event subscription and invocation.

\$\endgroup\$
  • \$\begingroup\$ This works, and the syntax is definitely an improvement - I had to make one additional change to my code to get the exact syntax I wanted: public Proc(Action<IDamageRolledHandler> subscribe, Action<IDamageRolledHandler> unsubscribe) While passing Subscribe and Unsubscribe off of Example as those arguments to Proc. \$\endgroup\$ – Chris Thompson Nov 11 '17 at 17:55
  • \$\begingroup\$ That could work too if you are looking for a deferred solution \$\endgroup\$ – Paulo Enmanuel Nov 12 '17 at 4:07
  • \$\begingroup\$ Yeah, I want to ensure that the Proc class takes control of its subscription, instead of having Example manage it. That makes more sense to me, and I'm not aware of any standards/best practices this would be violating. \$\endgroup\$ – Chris Thompson Nov 12 '17 at 6:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.