C# 委托

Posted 无声蝉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 委托相关的知识,希望对你有一定的参考价值。

在C#中,委托在语法上总是接受一个参数的构造函数,这个参数就是委托引用的方法。

例1:

public delegate int MethodDelegate(int x, int y);
private static MethodDelegate method;
static void Main(string[] args)

	method = new MethodDelegate(Add);
	Console.WriteLine(method(10,20));
	Console.ReadKey();


private static int Add(int x, int y)

	return x + y;

例2:

public delegate string GetString();
static void Main()

	int x=40;
	GetString firstStringMethod = new GetString(x.ToString);
	Console.WirteLine("String is 0",firstStringMethod());

  注:ToString后不能加括号,委托会自己推断。

一旦定义了委托类,基本就可实例化它的实例,就像处理一般类那样——所以把一些委托的实例放在数组中也是可以的。

使用委托的另一种方式——把方法组合到一个数组中来使用,这样就可以在循环中使用委托了


参考文章 C# 委托,定义及使用委托的几种形式:

第一:Delegate ,上述已经提过

第二:Func<T>

在使用 Func<T, TResult> 委托时,不必显式定义一个封装只有一个参数的方法的委托。

 以下示例简化了此代码,它所用的方法是实例化 Func<T, TResult> 委托,而不是显式定义一个新委托并将命名方法分配给该委托。

public class GenericFunc

   public static void Main()
   
      // 依旧是用命名方法实例化委托类型
      Func<string, string> convertMethod = UppercaseString;
      string name = "Dakota";
      // 依旧是通过委托实例调用该方法
      Console.WriteLine(convertMethod(name));
   

   private static string UppercaseString(string inputString)
   
      return inputString.ToUpper();
   

下面的示例演示如何声明和使用 Func<T, TResult> 委托。  

此示例声明一个 Func<T, TResult> 变量,并为其分配了一个将字符串中的字符转换为大写的 lambda 表达式。  

随后将封装此方法的委托传递给Enumerable.Select 方法,以将字符串数组中的字符串更改为大写。

static class Func

   static void Main(string[] args)
   
      // 声明了一个Func委托类型的变量selector并用Lambda表达式进行实例化 
      // 这个Lambda表达式将用来获取一个字符串并将这个字符串转化为大写并返回
      Func<string, string> selector = str => str.ToUpper();

      // 创建一个字符串数组
      string[] words =  "orange", "apple", "Article", "elephant" ;
      // 依次遍历这个字符串数组并调用委托实例selector进行处理
      IEnumerable<String> aWords = words.Select(selector);

      // 输出结果到控制台
      foreach (String word in aWords)
         Console.WriteLine(word);
   
      
/*
This code example produces the following output:

   ORANGE
   APPLE
   ARTICLE
   ELEPHANT
*/

第三:Action<T>

Action 委托:没有传入参数,也没有返回类型,即Void。如:

void Main(string[] args)
        
            Action say = SayHello;
            say();
        
        public static void SayHello( )
        
           Console.WriteLine("Say Hello");
        

Action<T> 委托:传入参数为T,没有返回类型。如:

void Main(string[] args)
        
            Action<string> say = SayHello;
            say("Hello");
        
        public static void SayHello(string word )
        
            Console.WriteLine(word);
        

其实ActionFunc的用法差不多,差别只是一个有返回类型,一个没有返回类型,当然Action也可以接匿名方法和Lambda表达式。

匿名方法:

void Main(string[] args)
        
            Action<string> say = delegate(string word)
            
                Console.WriteLine(word);
            ;
            say("Hello Word");
        

Lambda表达式:

static void Main(string[] args)
        
            Action<string> say = s => Console.WriteLine(s);
            say("Hello Word");
        

第四:Predicate<T>

//泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。
void Main(string[] args)
        
            Point[] points =  new Point(100, 200), 
            new Point(150, 250), new Point(250, 375), 
            new Point(275, 395), new Point(295, 450) ;
            Point first = Array.Find(points, ProductGT10);
            Console.WriteLine("Found: X = 0, Y = 1", first.X, first.Y);
            Console.ReadKey();
        
        private static bool ProductGT10(Point p)
        
            if (p.X * p.Y > 100000)
            
                return true;
            
            else
            
                return false;
            
        

使用带有 Array.Find 方法的 Predicate 委托搜索 Point 结构的数组。

如果 X 和 Y 字段的乘积大于 100,000,此委托表示的方法 ProductGT10 将返回 true。

Find 方法为数组的每个元素调用此委托,在符合测试条件的第一个点处停止。


  • 不限于数值类型的排序
  • 多播委托:委托数组,可以识别“+”和“+=”
  • 匿名委托
  • 事件其实就是委托,下面要单独开一张来总结

以上是关于C# 委托的主要内容,如果未能解决你的问题,请参考以下文章

VB 2015 的 闭包(Closure)

调用 lambda 表达式而不将其分配给委托

C# 中类型推断的优点和缺点是啥?

来自'??' 的 C# 类型推断(“var”)赋值空合并运算符

C#泛型对类型参数的推断

如何让 C# 编译器自动推断这些类型参数?