是否有任何 Null-Conditional Operator like for Events.. Button?.Click +=(ss,ee)

Is there any Null-Conditional Operator like for Events.. Button?.Click +=(ss,ee)

为什么事件没有空条件运算符?

例如,如果对象不为空,我有以下代码引发事件:

Button TargetButton =  null;

    if(IsRunning)
    {
       TargetButton = new ....
    }

TargetButton?.Click +=(ss,ee)=>{...}

// Compile-time error 
// The event 'EditorButton.Click' can only appear on the left hand side of += or -= 

简述:

还有其他选择吗?比通常使用 if(TargetButton != null ) ... raise event

为什么事件没有空条件运算符。它接受 null 吗? http://prntscr.com/pv1inc

事件只不过是围绕委托的 Add() 和 Remove() 访问器。然而,可能有点令人困惑的是 class 代码可以在事件名称下完全访问它(读取、归零、etic)。

调用它们的方式如下所示。我以 INotifyPropertyChanged:

为例
//Declaring the event
public event PropertyChangedEventHandler PropertyChanged;  

//the function that raises the Events.
private void NotifyPropertyChanged(
//That attribute is almost unique for the function of NotifyPropertyChange
//It puts in teh propertyName if nothing is given
//You just use normal paramters here
[CallerMemberName] String propertyName = "")  
{  
    //Nullcheck, Invoke with EventArgs containing the propertyName
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}  

我确实记得一个旧信息,您应该将事件列表复制到局部变量中。我认为这与多任务处理或枚举器更改有关。

//volatile so Optimisations will not cut it out
volatile var localCopy = PropertyChanged

问题与事件无关。

空条件运算符用于在引用为空时停止计算。

它不适用于作业的左侧或右侧。

如果你有:

public class Test
{
  public int Value;
  public void Method() { }
}

你不能写:

Test v;

v?.Value = 10;

int a = v?.Value;

因为如果 v 为 null,则不会计算 v.Value。

  • 那么= 10怎么办?

  • 或者a怎么办?

因此,在为空时为 null 的事件变量添加或删除事件处理程序时是一样的。

C# event is null

因此编译器错误不允许这样写。

这就是你不能写的原因:

TargetButton?.Click +=(ss,ee)=>{...}

因为如果 TargetButton 为空,(ss,ee)=>{...} 有什么用?

您可以说您希望编译器忽略它。

但是编译器不允许做这种不干净的事情。

我们可以写的是:

v?.Test();

此处 v 为 null,未调用该方法,一切正常,因为编译器不知道如何处理任何右边或左边的内容。

int a = v?.Value ?? 0;

此处如果 v 为空则使用 0。

Null-conditional operators ?. and ?[]

Null-coalescing operators ?? and ??=

Events 本身不为空。但您可以创建一个处理程序并将其分配给事件。

EventHandler handler = myEvent;
handler?.Invoke(args);