Why is it legal to call an action without taking it to anything?

My understanding of actions in C # is that they represent a specific version of the delegate, namely: without parameters and without a return type.

If I create such a class ...

class TrainSignal { public delegate void TrainsAComing(); public void HerComesATrain() { TrainsAComing(); } } 

... it will not compile since I did not create an instance of the delegate. However, if I replace the delegate definition with an Action, as shown below, it compiles:

 class TrainSignal { public Action TrainsAComing; public void HerComesATrain() { TrainsAComing(); } } 

I thought it was possible that the action is static or something like this (thereby allowing us to call it by their name without instantiating it), but this does not seem to be the case.

Can someone explain why the second block of code is legal?

+5
source share
2 answers

This line

 public delegate void TrainsAComing(); 

defines a public delegate type called TrainsAComing , nested inside your class. This would allow users to create delegates such as TrainSignal.TrainsAComing , but TrainSignal would not have a member to store an instance of such a delegate.

In other words, the delegate declaration does not define a member of the delegate type. For this you need another declaration:

 class TrainSignal { public delegate void TrainsAComing(); // The delegate type public TrainsAComing OnTrainsAComing; // The member of delegate type public void HerComesATrain() { OnTrainsAComing(); } } 

Action , on the other hand, is already a type similar to the delegate TrainsAComing from your example. Therefore, the definition

 public Action TrainsAComing; 

makes TrainsAComing member of TrainSignal , capable of storing a delegate.

+4
source

The Action field is a field like any other. This is a ref type, so the null field is initialized. You will get a NullReferenceException . It is completely safe, but not useful.

Maybe you would like to actually refer to a function?

 Action TrainsAComing = () => Console.WriteLine("..."); 

Or maybe confusion arises from the fact that the first piece of code declares a delegate type, and the second declares a delegate type field.

+3
source

Source: https://habr.com/ru/post/1242951/


All Articles