C foundation anonymous method example tutorial

  • 2020-10-23 20:15:49
  • OfStack

This article explains the use of C# anonymous methods in the form of examples and shares them with you for your reference. The details are as follows:

Anonymous methods are a new feature of the C# 2.0 language. Let's start with the simplest example:


class Program 
{ 
 static void Main(string[] args) 
 { 
  List<string> names = new List<string>(); 
  names.Add("Sunny Chen"); 
  names.Add("Kitty Wang"); 
  names.Add("Sunny Crystal"); 
   
  List<string> found = names.FindAll( new Predicate<string>(NameMatches)); 
 
  if (found != null) 
  { 
   foreach (string str in found) 
    Console.WriteLine(str); 
  } 
 } 
 
 static bool NameMatches(string name) 
 { 
  return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase); 
 }
}

This code initializes a list of strings (string list) at the beginning, looks for strings starting with "sunny" through the FindAll method of the list, and outputs all the results found.

We need to focus on List < T > FindAll method. This method takes 1 argument of Predicate < T > Type, return value List < T > Function of type. Note that Predicate < T > Is a generic delegate, which refers to functions that have only one argument of type T and return a Boolean value. You can see Predicate through tools like reflector < T > Is defined as follows:


public delegate bool Predicate<T>(T obj); 

At this point, we can sort of guess the implementation of the FindAll method. Namely for List < T > Call Predicate for each element in < T > If the function returns true, add it to the new list. After all the elements are traversed, the newly created list is returned to the caller. As follows:


public List<T> FindAll<T>(Predicate<T> match) 
{ 
 List<T> ret = new List<T>(); 
 foreach (T elem in items) 
 { 
  if (match(elem)) 
   ret.Add(elem); 
 } 
 return ret; 
} 

Therefore, for the above example, to call the FindAll method, we must first define a function with an argument of type string and a return value of type Boolean. In this function, we condition the argument and return true if the condition is met (i.e., with "sunny" as the starting string), otherwise we return false. Finally, pass this function as a parameter to FindAll. So you get the top code.

In the above example, in order to call the FindAll method, we have to define a new function, which is rarely used except for the FindAll method, and you have to give it a name. If there are multiple calls to the FindAll method in the program, or something similar, then the entire program will have a large number of "only one place to use" functions, making the code difficult to read and maintain.

Because of this problem, C# 2.0 introduced anonymous methods. Developers implementing a method need only give a list of the method's parameters (or even not) and the method's implementation, and do not need to care about the method's return value, let alone give the method a name. Crucially, anonymous methods are defined only where they are needed, keeping the code concise.

Anonymous methods are defined only where they are needed, using the delegate keyword, followed by the argument list, followed by the function body enclosed in curly braces of 1. The above code can be reproduced in the following form:


class Program 
{ 
 static void Main(string[] args) 
 { 
  List<string> names = new List<string>(); 
  names.Add("Sunny Chen"); 
  names.Add("Kitty Wang"); 
  names.Add("Sunny Crystal"); 
 
  List<string> found = names.FindAll( 
   delegate(string name) 
   { 
    return name.StartsWith("sunny", StringComparison.OrdinalIgnoreCase); 
   }); 
 
  if (found != null) 
  { 
   foreach (string str in found) 
    Console.WriteLine(str); 
  } 
 } 
 
 //static bool NameMatches(string name) 
 //{ 
 // return name.StartsWith("sunny", 
 //  StringComparison.OrdinalIgnoreCase); 
 //} 
} 

At this point, we don't need the NameMatches method at all, we just pass the anonymous method as a parameter to the FindAll method. The anonymous method itself does have a name, but we don't really care what it's called, so NET just picked a name for us.

Anonymous methods are used extensively in C# because delegates are very common as function arguments. We can also use anonymous methods when defining simple event handling. Such as:


ServiceHost host = new ServiceHost(typeof(FileTransferImpl)); 
host.Opened += delegate(object sender, EventArgs e) 
{ 
 Console.WriteLine("Service Opened."); 
};

Anonymous methods make it easy to use local variables, which simplifies programming compared to individually defined naming methods. For example, in the example above, if the Main function defines an integer local variable (number), you can use the number variable in the anonymous method definition of delegate (string name).

As mentioned earlier, when defining anonymous methods, you can omit even the argument list. Because the compiler can determine the signature of the function based on the signature of the delegate, and then simply give the function a name. The following code demonstrates this usage:


delegate void IntDelegate(int x); 
 
//  The way parameters are defined  
IntDelegate d2 = delegate(int p) { Console.WriteLine(p); }; 
//  Definition with no arguments (and no return value, of course)  
IntDelegate d3 = delegate { Console.WriteLine("Hello."); }; 

When using anonymous method definitions with no arguments and return values, there are two things to note:

1. If you need to handle arguments in your anonymous methods, you cannot declare them without defining a list of arguments. When you define anonymous methods, you need to give a list of arguments.
2. Anonymous methods with no arguments and return values can be referred to by a delegate with any form of signature.

The first point above is obvious, because you don't define a parameter list, so you can't use parameters. To illustrate point 2, look at the following code:


class Program 
{ 
 delegate void IntDelegate(int x); 
 delegate void StringDelegate(string y); 
 
 static void Output(IntDelegate id) 
 { 
 } 
 
 static void Output(StringDelegate sd) 
 { 
 } 
 
 static void Main(string[] args) 
 { 
  /* 
   * ERROR: The call is ambiguous between 
   *  Output(IntDelegate) 
   *    and 
   *  Output(StringDelegate) 
   */ 
  Output(delegate { }); 
 } 
} 

The above code does not compile because the compiler does not know whether to restore the anonymous method delegate {} to the function referred to by IntDelegate or StringDelegate. Only an explicit argument list can be given at this point, so that the compiler knows which Output function we want to call.

Hopefully this article has helped you with your C# programming


Related articles: