aAaeECBrefrEsAZZZC| G7474746VCZZCW~~ 6666}AXCBWBCB }AXBCBCB 8VC-

Action.` This is a function object. Action objects return no values. The Action type is similar to a void method. This generic type is found in the System namespace. `Void `void`To specify an Action,` we must have no return value. The Action must never return a value onto the evaluation stack. Often we use lambdas to specify Actions. `Lambdas `lambda`Start.` The Actions point to anonymous functions. These functions cannot return values onto the evaluation stack. An Action instance can receive parameters, but cannot return values. `Return `return`So: `An Action instance is similar to a void method. The program shows how to Invoke the Action instances.`Notes, above program.` We use Action with 3 lambda expressions. The first Action instance uses the constructed type Action<int>, and an explicit parameter list in the lambda expression. `It receives one argument when invoked. It returns no result—it is a void delegate method.`Notes, continued.` The second and third Action instances also return no value. The second Action receives 2 int parameters. The third Action receives no parameters. `Int `int`Notes, Invoke.` The Invoke method receives a number of arguments equal to the specific type of Action. We must specify these arguments in the Action type declaration. `Generic Method `generic-method`This information is determined at compile-time, before runtime. If a program compiles, it uses the correct argument types.`A benchmark.` How much slower are delegate method calls than direct method calls? To test this, we use the Action type with a single parameter. `Overview: `This program introduces the Method1 method, which contains some dummy code for testing.`First: `In the first loop, Method1 (which uses no Action) is called directly 100 million times.`Second: `In the second loop, an Action instance that points to Method1 is invoked the same number of times.`Notes, above benchmark.` For a method with one parameter and no return value, the Action invocation costs more than 3 ns extra each time. This is unlikely to cause many performance problems.`Funcs.` What is the difference between Action and Func? The Action type receives parameters but does not return a parameter. Func receives parameters and returns a result value. `So: `An Action instance never returns anything, while the Func always returns something.`Func `func`Abstract.` Next, we compare abstract methods. An Action<int> can be an instance that points to any function that receives an int parameter. `However: `You can design an abstract class with an abstract method that also can be used in this way.`Abstract `abstract`Next: `In the following program, we test such an abstract class against an Action<int>.`Benchmark `benchmark`Results, above benchmark.` The Action was slower to call than the method from the abstract class reference. If you can use abstract classes instead of Actions, this will be faster.`Dictionary.` It is possible to use Action as the value in a Dictionary instance. This makes it possible to call functions by a string key. `Dictionary `dictionary`In this example, we invoke two static void methods based on simple string keys.`Static Method `static`Idea: `You could use a Dictionary of an abstract class. Then, instantiate each method as an instance of a derived class.`Inheritance `inheritance`A summary.` Programs use Action for many purposes. The Action type specifies a function object that can receive parameters, but never returns a value onto the stack. `Thanks to Turker Tunali for helping clarify the Action descriptive text. All contributions are appreciated.`Void methods.` Action instances are void methods. As higher-order procedures, they can be passed around as objects. This is powerful.

UVX172:DQbJA%{F9F9F9F9MzFi'azzF'aVF'{gFFFaaVDQ!JAiy%{_wgzyqzgby,`wiy{g3y,`wiy{3'0#O'0#O5u?cgi{mxq+DQ!JBcgiJBcgiJA?cgi%yqgbzyqzgbiyy,`wiygg3y,`wiy3'0#O'0#O5uDQ JA%-Pyq-Pyqyqb?c'?c' VVVVV { UVU{X UUVEV Action instances. UUVFirst eV uses one parameter. UUVSecond eV uses two parameters. UUVThird eV uses no parameter. UUVNone have Vs. UUXActionX<V> eV1 = UUU(Vx) => VX"V {0}"X, x); UUXActionX<V, V> eV2 = UUU(x, y) => VX"V {0}V{1}"X, x, y); UUXActionX eV3 = UUU() => VX"Done"X);X UUVCall the anonymous mVs. UUXeV1.Invoke(1); UUeV2.Invoke(2, 3); UUeV3.Invoke(); U} } X V 1 V 2V3 DoneX VV; V VV { Uconst V_maxV100000000; UVU{X UUVCV Action delegate VMV1. UUXAction<V> actionVVAction<V>(MV1)VUUvar s1VV.VNew(); UUV(ViV0; i < _max; i++) UU{X UUUVDirect call. UUUXMV1(5); UU} UUs1V; UUvar s2VV.VNew(); UUV(ViV0; i < _max; i++) UU{X UUUVDelegate call. UUUXaction.Invoke(5); UU} UUs2V; UUV(V(s1.V * 1000 * 1000) / UUU_max).ToV("0.00 ns")); UUV(V(s2.V * 1000 * 1000) / UUU_max).ToV("0.00 ns")); UUV.V(); U} UVVMV1(Vparam) U{X UUVDummy. UUXVparamV-1) UU{ UUUthrow VV(); UU} U} } X X0.32 ns 3.52 nsX VV; V abstract VA { UVabstract VMVA(Vy); } VAB : A { UVoverride VMVA(Vy) U{ U} } VV { UVVMVA(Vy) U{ U} UVU{ UUA abstVVAB(); UUabst.MVA(0)VUUAction<V> actionVVAction<V>(MVA); UUaction.Invoke(0)VUUconst VmaxV100000000; UUvar s1VV.VNew(); UUV(ViV0; i < max; i++) UU{ UUUabst.MVA(i); UUUabst.MVA(i); UU} UUs1V; UUvar s2VV.VNew(); UUV(ViV0; i < max; i++) UU{ UUUaction.Invoke(i); UUUaction.Invoke(i); UU} UUs2V; UUV(V(s1.V * 1000000) / UUUmax).ToV("0.00 ns")); UUV(V(s2.V * 1000000) / UUUmax).ToV("0.00 ns")); UUV.V(); U} } X X3.54 ns 6.68 nsX VV; V VV { UVU{ UUDV<V, Action> dictVVDV<V, Action>(); UUdict["cat"]VVAction(Cat); UUdict["dog"]VVAction(Dog)VUUdict["cat"].Invoke(); UUdict["dog"].Invoke(); U} UVVCat() U{ UUVX"CAT"X); U} UVVDog() U{ UUVX"DOG"X); U} } X CAT DOGX

$f73fAction type and Invoketests Action invocationbenchmarks abstractDictionary with Action