为什么在没有首先将其分配给任何东西的情况下调用操作是合法的
本文关键字:情况下 调用 操作 任何东 分配 为什么 | 更新日期: 2023-09-27 18:34:24
我对 C# 中的操作的理解是,它们只是委托的特定版本,即没有参数和返回类型的委托。
如果我创建一个这样的类...
class TrainSignal
{
public delegate void TrainsAComing();
public void HerComesATrain()
{
TrainsAComing();
}
}
。它不会编译,因为我还没有创建委托的实例。但是,如果我将委托定义替换为如下所示的操作定义,它将编译:
class TrainSignal
{
public Action TrainsAComing;
public void HerComesATrain()
{
TrainsAComing();
}
}
我想也许一个动作是静态的或类似的东西(从而允许我们用它的名字来调用它而不实例化它),但事实似乎并非如此。
谁能解释为什么第二个代码块是合法的?
此行
public delegate void TrainsAComing();
定义一个名为 TrainsAComing
的公共委托类型,嵌套在类中。这将允许用户创建类型为 TrainSignal.TrainsAComing
的委托,但TrainSignal
将没有成员来存储此类委托的实例。
换句话说,委托的声明不定义委托类型的成员。您需要另一个声明:
class TrainSignal
{
public delegate void TrainsAComing(); // The delegate type
public TrainsAComing OnTrainsAComing; // The member of delegate type
public void HerComesATrain()
{
OnTrainsAComing();
}
}
另一方面,Action
已经是一种类型,类似于示例中delegate TrainsAComing
。因此,定义
public Action TrainsAComing;
使TrainsAComing
成为能够存储委托的TrainSignal
的成员。
Action
字段与其他字段一样。它是 ref 类型,因此null
初始化该字段。您将收到NullReferenceException
。这是完全安全的,但没有用。
也许你的意思是实际引用一个函数?
Action TrainsAComing = () => Console.WriteLine("...");
或者,混淆来自这样一个事实,即第一个代码段声明委托类型,第二个代码段声明委托类型的字段。