1

I'm subscribing to an event generated by a class that might be null as follows:

if (eventGeneratingClass != null)
  eventGeneratingClass.myEvent += myHandler;

In the event generating class a construct like

myEvent?.Invoke(this, new EventArgs());

can be used. I was wondering if a similar construct could be used when (de)subscribing to an event, e.g.:

eventGeneratingClass?.myEvent += myHandler;
eventGeneratingClass?.myEvent -= myHandler;

I've found both Is there a shorthand for addition assignment operator for nullables that sets the value if null? and How to call custom operator with Reflection

which lead me to: Operator Overloading Usage Guidelines

Which lead me to trying

eventGeneratingClass?.myEvent.op_AdditionAssignment(myHandler);
eventGeneratingClass?.myEvent.op_SubtractionAssignment(myHandler);

but it doesn't seem that an event has an op_AdditionAssignment memberfunction or at least provides me with the error

the event 'EventGeneratingClass.myEvent' can only appear on the left hand side of += or -=...

Which is where I got stuck...

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Lanting
  • 3,060
  • 12
  • 28
  • You're probably looking for add/remove https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/add .. *but* I don't think that'll work if your object itself is null, because there won't be anything to call the add/remove of, haven't tried though – KMoussa Apr 06 '18 at 08:49
  • You were looking for `eventGeneratingClass?.add_myEvent(myHandler)` but this won't work anyway, compiler will say "cannot explicitly call operator or accessor". So you have to just live with the fact you have to use `if` in this case. – Evk Apr 06 '18 at 08:52

3 Answers3

3

The null conditional operation ?. returns null when the left side expression is null.

So in

eventGeneratingClass?.myEvent += myHandler

if eventGeneratingClass is null then eventGeneratingClass?.myEvent is null. And trying to attach an event listener to null will result in a NullReferenceException.

While the ?. operator does make handling nulls easier, it doesn't eliminate handling them.

Richard
  • 106,783
  • 21
  • 203
  • 265
1

If you are looking for a solution using null-conditional operators than it seems you are out of luck. From the C# draft specification:

Null-conditional expressions as statement expressions

A null-conditional expression is only allowed as a statement_expression (Expression statements) if it ends with an invocation. Grammatically, this requirement can be expressed as:

null_conditional_invocation_expression
    : primary_expression null_conditional_operations '(' argument_list? ')'
    ;

This is a special case of the grammar for null_conditional_expression above. The production for statement_expression in Expression statements then includes only null_conditional_invocation_expression.

So you would need to call += as +=(myHandler) (i.e. eventGeneratingClass?.myEvent?.+=(myHandler)), which is not possible.

Community
  • 1
  • 1
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
0

You could use an extension method:

public static class Extensions
{
    public static void IfNotNull<T>(this T instance, Action<T> action)
    {
        if (instance != null)
        {
            action(instance);
        }
    }
}

Then call

someInstance.IfNotNull(_ => _.SomethingHappened += (sender, eventArgs) =>
{
    // code
});

But then again you could even use the if clause, since the extension method does not make the code less verbose.

Peter Perot
  • 1,003
  • 1
  • 10
  • 15