Before Make sure to read about delegate here
Action is just a built‑in delegate for “do something and don’t return a value.” So Action is the same shape as a custom delegate that returns void.
If delegates are “function references,” then Action is the ready‑made one for void.
Same example as delegate, using Action
// Built-in delegate: Action<T> == delegate void Something(T)
static void FormalSay(string name) => Console.WriteLine($"Hello, {name}.");
static void FriendlySay(string name) => Console.WriteLine($"Hey {name}!");
Action<string> say = FormalSay; // reference to a void-returning function
say("Ava"); // Hello, Ava.
say = FriendlySay; // swap behaviour
say("Ava"); // Hey Ava!
▶️ Tiny runnable sample
welldone if you have reached here, bellow I'm trying to explain the action in an example more closed to real world(the same example as delegate)
Scenario: train ticket AddOns with Action
Imagine you have a Train ticket and you want to add some Extras to your ticket such as Insurance, Coffee , ...
let's write this code without Actions and then with Actions.
Basics:
First Lets have TrainTicket
Model:
public class TrainTicket
{
public string TicketId { get; }
public decimal Price { get; set; } // base + add-ons
public decimal Discount { get; set; } // from promo
public decimal FinalPrice => Price - Discount;
public List<string> Extras { get; } = new();
public TrainTicket(string ticketId, decimal basePrice)
{
TicketId = ticketId;
Price = basePrice;
}
}
and now Let's consider we have these AddOns:
public static class TrainAddOns
{
public static void AddInsurance(TrainTicket ticket)
{
ticket.Price += 7m;
ticket.Extras.Add("Insurance");
}
public static void CoffeeToSeat(TrainTicket ticket)
{
ticket.Price += 3m;
ticket.Extras.Add("Coffee to seat");
}
public static void FoodDelivery(TrainTicket ticket)
{
ticket.Price += 8m;
ticket.Extras.Add("Food delivered to seat");
}
public static void ExtraLegroom(TrainTicket ticket)
{
ticket.Price += 12m;
ticket.Extras.Add("Extra legroom");
}
}
Apply AddOns Without Actions
We get a addOns as a string and add the extras with a switch
statement:
public static TrainTicket ApplyAddOns(TrainTicket ticket, IEnumerable<string> addOns)
{
foreach (var name in addOns)
{
switch (name)
{
case "insurance":
{
TrainAddOns.AddInsurance(ticket);
break;
}
case "coffee":
{
TrainAddOns.CoffeeToSeat(ticket);
break;
}
case "food":
{
TrainAddOns.FoodDelivery(ticket);
break;
}
}
}
return ticket;
}
and here is how we call this method to apply addons:
ApplyAddOns(ticket, new List<string> { "insurance", "coffee", "food" });
Apply AddOns With Actions
What makes the code more simple is using the code and passing the actions( ref to void function) to the ApplyAddOns
method. this Method doesn't need to know the implementation, it will call the action so that it can apply the AddOns as expected.
public static TrainTicket ApplyAddOns(TrainTicket ticket, List<Action<TrainTicket>> addOnActions)
{
foreach (var addOnAction in addOnActions)
{
addOnAction(ticket);
}
return ticket;
}
and here is how we call this metgod to apply addons:
ApplyAddOns(ticket,new List<Action<TrainTicket>>
{
TrainAddOns.AddInsurance,
TrainAddOns.CoffeeToSeat,
TrainAddOns.FoodDelivery
});
▶️ Runnable sample: Apply AddOns Without Action
▶️ Runnable sample: Apply AddOns With Action
Top comments (0)