订阅可空类

时间:2018-04-06 08:40:49

标签: c# events nullable

我订阅了一个由类生成的事件,该事件可能为null,如下所示:

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

在生成类的事件中有一个类似

的构造
myEvent?.Invoke(this, new EventArgs());

可以使用。我想知道在(de)订阅事件时是否可以使用类似的构造,例如:

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

我发现了两者 Is there a shorthand for addition assignment operator for nullables that sets the value if null?How to call custom operator with Reflection

引导我:Operator Overloading Usage Guidelines

这导致我尝试

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

但似乎事件没有op_AdditionAssignment成员函数或者至少为我提供了错误

  

事件' EventGeneratingClass.myEvent'只能出现在+ =或 - = ...

的左侧

我被困在哪里......

3 个答案:

答案 0 :(得分:3)

当左侧表达式为空时,空条件操作?.返回null。

所以在

eventGeneratingClass?.myEvent += myHandler

如果eventGeneratingClass为null,则eventGeneratingClass?.myEvent为空。尝试将事件侦听器附加到null将导致NullReferenceException

虽然?.运算符确实使处理空值更容易,但它并没有消除处理它们。

答案 1 :(得分:1)

如果您正在寻找使用空条件运算符的解决方案,那么您似乎运气不好。来自C# draft specification

  

空条件表达式作为语句表达式

     

如果null-conditional表达式以调用结束,则它只允许作为statement_expression(Expression语句)使用。在语法上,这个要求可以表示为:

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

这是上面null_conditional_expression的语法的特例。然后,Expression语句中的statement_expression生成仅包含null_conditional_invocation_expression。

因此,您需要将+=称为+=(myHandler)(即eventGeneratingClass?.myEvent?.+=(myHandler)),这是不可能的。

答案 2 :(得分:0)

您可以使用扩展方法:

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

然后致电

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

但是你甚至可以使用if子句,因为扩展方法不会使代码更简洁。