【问题标题】:Subscribe to events of a nullable class订阅可空类的事件
【发布时间】:2018-09-16 05:51:44
【问题描述】:

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

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

在事件生成类中类似的构造

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

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

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' 只能出现在 += 或 -= 的左侧...

这是我卡住的地方...

【问题讨论】:

  • 您可能正在寻找添加/删除 docs.microsoft.com/en-us/dotnet/csharp/language-reference/… .. 但是如果您的对象本身为空,我认为这不会起作用,因为不会没有什么可以调用添加/删除的,虽然没有尝试过
  • 您正在寻找eventGeneratingClass?.add_myEvent(myHandler),但这无论如何都不起作用,编译器会说“无法显式调用运算符或访问器”。因此,在这种情况下,您必须接受必须使用 if 的事实。

标签: c# events nullable


【解决方案1】:

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

所以在

eventGeneratingClass?.myEvent += myHandler

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

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

【讨论】:

    【解决方案2】:

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

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

    空条件表达式仅在以调用结束时才允许作为 statement_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)),这是不可能的。

    【讨论】:

      【解决方案3】:

      您可以使用扩展方法:

      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 子句,因为扩展方法不会使代码更简洁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        • 2010-11-04
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多