Reputation: 11201
If I searched I will definitely get examples of showing what is a Delegate and Action. I have read the basic books giving examples of delegate.
But what I want to know is their use in the real world. Please do not give Hello World example or the Animal class they are far too basic
For e.g. :
Upvotes: 41
Views: 41148
Reputation: 724
The Real world example code that has been repeatedly requested, has already been provided in an earlier answer by "Console.WriteLine" user.
As far as to why it has been provided, from what I understood, Action is a way to save keeping on defining new delegates of your own. Since it is a predefined delegate of particular signature types, you save the hassle of creating different delegates for each intended purpose. You just use the predefined Action delegate to point to your methods and run them. Same is the case with Func delegates.
More of a convenience really, rather than actual new functionality. Helps keep your code short and understandable, with less hassle.
As far as your point-wise questions,
No difference. Action is a predefined delegate, intended to save you the trouble of repeatedly defining new delegates.
Typically, a delegate (and action) is used in places where you need to have table-driven functionality. i.e., maybe a dictionary of methods corresponding to some particular requirement. Note that using Action here makes it easy to change the final method called, to point to some other method dynamically (maybe based upon some settings selected by user?)
class Program
{
static void Main()
{
Dictionary<string, Action> dict = new Dictionary<string, Action>();
dict["loadFile"] = new Action(LoadFile);
dict["saveFile"] = new Action(SaveFile);
dict["loadFile"].Invoke();
dict["saveFile"].Invoke();
}
static void SaveFile()
{
Console.WriteLine("File saved!");
}
static void LoadFile()
{
Console.WriteLine("Loading File...");
}
}
Another typical usage is for callback methods. Example would be where you use a BubbleSort class, passing the comparator method as a delegate to the class, which would be used by the BubbleSort class to allow your code to define the comparison logic, while taking care of everything else. This can also be used from threads which you've started, and the thread calls the delegate when some intermediate actions need to be informed to your code.
You can refer this SO post to see a great example of the above. https://stackoverflow.com/a/3794229/1336068
The only reason I can think of not using them when the situation demands it, is if your delegate is going to be called millions of times in a short duration. There is a slight overhead involved, and if this is causing an application lag, then you might have to find a better way to solve this using direct reference to your functions, instead of through a delegate.
When you use them gratuitously without any real need. Otherwise, in most situations, they can be an elegant way to solve the above scenarios.
Also, read this SO answer to see the distinctions between normal methods, delegates to get a better understanding of where to use delegates/action/func https://stackoverflow.com/a/17380580/1336068
Upvotes: 6
Reputation: 5261
When you define a delegate you are essentially defining the signature of a method (return type and arguments).
An Action is a delegate which has already been defined (void return and no args).
public delegate void Action()
You can go to definition and see it yourself. Or here in the docs. http://msdn.microsoft.com/en-us/library/system.action.aspx
I almost always use the existing generic delegates (of which action is one) when the signature of the method I'm looking for matches the supported signatures. A nice thing about using the generic delegates is that they are well known. Most dev's know that an Action is void/void. If I was to define my own version of Action everyone would need to look up it's signature, and I just duplicated something which already exists.
For examples... Action happens to be a bit more rare since the purpose of a void/void method can only be for mutation. Func is very common (also a generic delegate). There are examples of it's usage all over the framework, especially in linq. Look at .where for instance. http://msdn.microsoft.com/en-us/library/bb534803.aspx . It's a Func meaning it takes an element of the type of the collection you are working on as a parameter and returns a bool. In context of the where statement having the Func return true means to include it in the results vice versa for false.
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Upvotes: 28
Reputation: 764
What is Action: Quite simply Action,Func<>,Predicate all are of type delegate.
Why we need Action: Action encapsulates different number of parameters and different type of return type which suffice for application development in many cases. These are provided in System namespace. You are free to create your own delegate.
Please note there are 17 different types of Action and Func each with zero to 16 parameterized generic arguments.
Action always has no return value. Func has a single parameterized generic return type.
IMHO, Predicate delegate was not needed to be defined as its really equivalent to Func that takes an arg and returns bool.
Upvotes: 6
Reputation: 2654
Action
is a Delegate
. It is defined like this:
public delegate void Action();
You could create your own delegate types similarly to how you would create abstract methods; you write the signature but no implementation. You then create instances of these delegates by taking the reference of a method.
class Program
{
public static void FooMethod()
{
Console.WriteLine("Called foo");
}
static void Main()
{
Action foo = FooMethod; // foo now references FooMethod()
foo(); // outputs "Called foo"
}
}
Upvotes: 44
Reputation: 443
Since Kenneth & Siege already pointed out the code & MSDN I will just try to fill in with the real world example.
Consider a delegate that defines "moving".
An 'Action' delegate in real world would be 'Run' or 'Walk'. You don't care at what speed you move, what route you take or report the time it took to move.
A non-Action delegate could for example define at what speed you run and return the time it took to complete it.
public delegate void MoveAction();
public delegate int MoveDelegate(int speed);
Extending Siege's examples ..
class Program
{
public static void Run()
{
Console.WriteLine("Running");
}
public static int RunAtSpeed(int speed)
{
// logic to run @ speed and return time
Console.WriteLine("Running @ {0}", speed);
return 10;
}
public static int WalkAtSpeed(int speed)
{
// logic to walk @ speed and return time
Console.WriteLine("Walking @ {0}", speed);
return 20;
}
static void Main()
{
Action foo = Run;
foo();
MoveDelegate run = RunAtSpeed;
int result1 = run(5);
MoveDelegate walk = WalkAtSpeed;
int result2 = walk(1);
}
}
Upvotes: 11