Function assignments - When are these good? Advantages and disadvantages?

Markus Freitag 3,786 Reputation points
2022-11-09T19:29:02.077+00:00

Hello,
For what do I need function assignments?
Can someone please explain this to me.
Very gladly with a practical example. Thanks in advance.
Criteria when I need to use this, or better should.

Maybe like this? Can it be?

DoWorkWithThreeParametersAndFunction(int arg1, int arg2, int arg3, CallFunc1)  
DoWorkWithThreeParametersAndFunction(int arg1, int arg2, int arg3, CallFunc2)  
DoWorkWithThreeParametersAndFunction(int arg1, int arg2, int arg3, CallFunc3)  
  
  
// ################ Variant Simple ########  
static void Main(string[] args)  
{  
    DoWorkWithOneParameter(1); // Print 1  
    DoWorkWithTwoParameters(1, 2); // Print 1-2  
    DoWorkWithThreeParameters(1, 2, 3); //Print 1-2-3  
}  
public static void DoWorkWithOneParameter(int arg)  
{  
    Console.WriteLine(arg);  
}  
  
public static void DoWorkWithTwoParameters(int arg1, int arg2)  
{  
    Console.WriteLine(arg1 + "-" + arg2);  
}  
  
public static void DoWorkWithThreeParameters(int arg1, int arg2, int arg3)  
{  
    Console.WriteLine(arg1 + "-" + arg2 + "-" + arg3);  
}  
  
  
// ################ Variant one ########  
static void Main(string[] args)  
{  
    Action<int> firstAction = DoWorkWithOneParameter;  
    Action<int, int> secondAction = DoWorkWithTwoParameters;  
    Action<int, int, int> thirdAction = DoWorkWithThreeParameters;  
  
    firstAction(1); // Print 1  
    secondAction(1, 2); // Print 1-2  
    thirdAction(1, 2, 3); //Print 1-2-3  
}  
  
public static void DoWorkWithOneParameter(int arg)  
{  
    Console.WriteLine(arg);  
}  
  
public static void DoWorkWithTwoParameters(int arg1, int arg2)  
{  
    Console.WriteLine(arg1 + "-" + arg2);  
}  
  
public static void DoWorkWithThreeParameters(int arg1, int arg2, int arg3)  
{  
    Console.WriteLine(arg1 + "-" + arg2 + "-" + arg3);  
}  
  
  
  
// ################ Variant two ############  
  
  
static void Main(string[] args)  
{  
    Action act = () =>  
    {  
        Console.WriteLine("No Parameter");  
    };  
  
    Action<int> actWithOneParameter = (arg1) =>  
        {  
            Console.WriteLine("Par: " + arg1);  
        };  
  
    Action<int, int> actWithTwoParameter = (arg1, arg2) =>  
        {  
            Console.WriteLine("Par1: " + arg1 + ", Par2: " + arg2);  
        };  
  
    act();  
    actWithOneParameter(1);  
    actWithTwoParameter(1, 2);  
}  
  
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
{count} votes

1 answer

Sort by: Most helpful
  1. P a u l 10,496 Reputation points
    2022-11-09T20:42:33.32+00:00

    Variants one & two are examples of actions rather than functions. In C# a function (or Func<T>) is something callable that returns a value (i.e. T in the previous case), whereas an action (or Action) is something callable that doesn't return a value. An Action is analogous of a void returning method.

    Functions are handy for injecting some of your consumer code into the execution of another function.

    For example, you have a list of users & you want a list of all the user's full names instead. You don't want to have to write a loop just to convert a User to a string, you just want to express the transformation & have it done for you, so you use a function that does the loop for you (i.e. IEnumerable<T>.Select).

    All you want to do is define how a User is transformed into a string, which you can do by passing a Func<User, string> inline (where the User represents the input of the function, and the last parameter string refers to the output of the function):

       IEnumerable<User> users = new User[] {  
       	new User { FirstName = "John", LastName = "Doe" }  
       };  
         
       IEnumerable<string> fullNames = users.Select(user => $"{user.FirstName} {user.LastName}");  
         
       class User {  
       	public string FirstName { get; set; }  
       	public string LastName { get; set; }  
       }  
    

    The obvious benefit of this is that it's more expressive, because you're eliminating boilerplate & potential mistakes. You're soaking that up into Select and all you're just describing to it how you want it to transform the data (when it ultimately yields the elements).