C#进阶-委托(Delegrate)

简介: 类似于 C 或 C++ 中函数的指针,委托是C#的函数指针,是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。本篇文章我们将讲解C#里委托的类型及如何使用。委托的语法第一次接触难免感到陌生,最好的学习方式就是在项目中多去使用,相信会有很多感悟。

委托

一、声明和实例化委托

委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同参数和返回值(或一样没有参数或返回值)的方法。

修饰符delegate返回值类型委托名(参数列表); //声明委托委托名委托对象名=new委托名(方法名); //实例化委托
namespaceDelegrate{
/*也可以在namespace里声明委托*///public delegate void FuncDelegrate(); //public delegate string FuncDelegrateString(string x);classProgram  {
/*声明委托*/publicdelegatevoidFuncDelegrate(); //无参无返回值委托publicdelegatestringFuncDelegrateString(stringx);//有参有返回值委托staticvoidMain(string[] args)
    {
/*实例化委托*/FuncDelegratefuncDelegrateA=newFuncDelegrate(Hello);
funcDelegrateA();
FuncDelegrateStringfuncDelegrateB=newFuncDelegrateString(Hello);
funcDelegrateB("xxx");
    }
publicstaticvoidHello()
    {
Console.WriteLine("Hello");
    }
publicstaticstringHello(stringx)
    {
Console.WriteLine("Hello,"+x);
return"Hello";
    }
  }
}
/*输出结果*/HelloHello,xxx

二、委托数组

委托数组存储相同委托的方法,可以通过遍历数组依次执行里面委托的方法。

委托名[] 委托对象名= {委托的方法1, 委托的方法2, ...}
namespaceDelegrate{
classProgram  {
/*声明委托*/publicdelegatevoidFuncDelegrate(); //无参无返回值委托publicdelegatestringFuncDelegrateString(stringx);//有参有返回值委托staticvoidMain(string[] args)
    {
//无参数无返回值委托数组FuncDelegrate[] funcArrayA= { Hello, World };
foreach (FuncDelegratefuncinfuncArrayA)
      {
func();
      }
//带参数带返回值的委托的数组FuncDelegrateString[] funcArrayB= { Hello, World };
foreach (FuncDelegrateStringfuncinfuncArrayB)
      {
FuncAry(func, "Damon");
      }
    }
publicstaticvoidFuncAry(FuncDelegrateStringfunc, stringvalue)
    {
Console.WriteLine("");
Console.WriteLine("方法"+GetFunctionName(func) +"返回值是"+func(value));
     }
publicstaticvoidHello()
    {
Console.WriteLine("Hello");
    }
publicstaticvoidWorld()
    {
Console.WriteLine("World");
    }
publicstaticstringHello(stringx)
    {
Console.WriteLine("Hello,"+x);
return"Hello";
    }
publicstaticstringWorld(stringx)
    {
Console.WriteLine(x+"'s World");
returnx;
    }
  }
}
/*输出结果*/HelloWorldHello,Damon方法Hello返回值是HelloDamon's World方法World返回值是Damon

三、Action和Func

Action和Func都是.NET Framework内置的泛型委托,免声明直接实例化调用。

/* Action是.NET Framework内置的泛型委托,要求委托必须无返回值 */Action<参数类型>委托对象名=方法名//有参情况Action委托对象名=方法名//无参情况
/* Func是.NET Framework内置的泛型委托,支持有参有返回值 */Func<返回类型>委托对象名=方法名Func<参数, 返回类型>委托对象名=方法名Func<参数, 参数, 返回类型>委托对象名=方法名//更多参数同理
namespaceDelegrate{
classProgram  {
/*声明委托*/publicdelegatevoidFuncDelegrate(); //无参无返回值委托publicdelegatestringFuncDelegrateString(stringx);//有参有返回值委托staticvoidMain(string[] args)
    {
//Action是.NET Framework内置的泛型委托,要求委托必须无返回值/* Action<参数类型> 委托对象名 = 方法名 */Action[] actions= { Hello, World };
foreach (Actionfuncinactions)
      {
func();
      }
//Func是.NET Framework内置的泛型委托,支持有参有返回值//Func <返回类型> 委托对象名 = 方法名Func<int>func1=ReturnIntValue;
//Func <参数, 返回类型> 委托对象名 = 方法名Func<int, string>func2=World;
//Func <参数, 参数, 返回类型> 委托对象名 = 方法名(更多参数同理)Func<string, string, string>func3=World;
Func<int, string>[] funcArrayC= { Hello, World };
foreach (Func<int, string>funcinfuncArrayC)
      {
FuncAry(func, 114514);
      }
    }
publicstaticvoidFuncAry(FuncDelegrateStringfunc, stringvalue)
    {
Console.WriteLine("");
Console.WriteLine("方法"+GetFunctionName(func) +"返回值是"+func(value));
     }
publicstaticvoidHello()
    {
Console.WriteLine("Hello");
    }
publicstaticvoidWorld()
    {
Console.WriteLine("World");
    }
publicstaticstringHello(stringx)
    {
Console.WriteLine("Hello,"+x);
return"Hello";
    }
publicstaticstringWorld(stringx)
    {
Console.WriteLine(x+"'s World");
returnx;
    }
publicstaticstringWorld(intx)
    {
Console.WriteLine(x+"'s World");
return"World(int x)";
    }
publicstaticintReturnIntValue()
    {
return1;
    }
  }
}
/*输出结果*/HelloWorldHello,114514方法Hello返回值是Hello(intx)
114514's World方法World返回值是World(intx)

四、匿名委托

//这里的Func和delegate都是系统自带不需要声明Func<T>委托对象名=delegate(方法参数){ 
方法体}
namespaceDelegrate{
classProgram  {
staticvoidMain(string[] args)
    {
//匿名方法/* Func<T> 委托对象名 = delegate(方法参数){ 方法体 }; */Func<int, string>AnonymousDelegate=delegate (intx)
      {
return"1";
      };
    }
  }
}

五、委托的多播

委托对象可使用 “+” 运算符进行合并相同类型的委托,也可使用 “-” 运算符移除任一合并委托中的委托。一个合并委托调用它所合并的N个委托。在实际工作中,我们常常创建一个委托被调用时要调用的方法的调用列表。

委托名委托对象A;
委托名委托对象B=new委托名(方法名);
委托名委托对象C=new委托名(方法名);
委托对象A=委托对象B;
委托对象A+=委托对象C;
委托对象A-=委托对象C;
namespaceDelegrate{
classProgram  {
/*声明委托*/publicdelegatevoidFuncDelegrate(); //无参无返回值委托publicdelegatestringFuncDelegrateString(stringx);//有参有返回值委托staticvoidMain(string[] args)
    {
//委托的多播FuncDelegrateStringfds;
FuncDelegrateStringfds1=newFuncDelegrateString(Hello);
FuncDelegrateStringfds2=newFuncDelegrateString(World);
fds=fds1;
fds+=fds2;//表示在委托列表里添加//fds -= fds2;//表示从委托列表里去除fds("Damon");
//第二种写法FuncDelegratefb1=newFuncDelegrate(StaticFeedbackFunc);//这里直接调用的静态方法Programp=newProgram();
FuncDelegratefb2=newFuncDelegrate(p.FeedbackFunc);//非静态方法需要实例化调用FuncDelegratefbChain=null;
fbChain= (FuncDelegrate)Delegate.Combine(fbChain, fb1);//和+=一样fbChain= (FuncDelegrate)Delegate.Combine(fbChain, fb2);
fbChain= (FuncDelegrate)Delegate.Remove(fbChain, newFuncDelegrate(p.FeedbackFunc));//和-=一样    }
publicstaticstringHello(stringx)
    {
Console.WriteLine("Hello,"+x);
return"Hello";
    }
publicstaticstringWorld(stringx)
    {
Console.WriteLine(x+"'s World");
returnx;
    }
publicstaticvoidStaticFeedbackFunc()
   {
Console.WriteLine("StaticFeedbackFunc()");
   }
publicvoidFeedbackFunc()
   {
Console.WriteLine("FeedbackFunc()");
    }
  }
}
/*输出结果*/Hello,DamonDamon's WorldStaticFeedbackFunc()

六、事件

事件(Event)是类或者对象向其他类或对象通知发送的事情的一种特殊签名的委托。事件使用event关键词来声明,他的返回值是一个委托类型。

publicevent委托类型事件名;
namespaceDelegrate{
/*声明委托*/publicdelegatevoidFuncDelegrate(); //无参无返回值委托classProgram  {
staticvoidMain(string[] args)
    {
//事件/* public event 委托类型 事件名; */DelegrateEventdelegrateEvent=newDelegrateEvent();
delegrateEvent.DelegateEvent+=Hello;//类似delegrateEvent.DelegateEvent+=World;
delegrateEvent.DelegateEvent-=World;
    }
publicstaticvoidHello()
    {
Console.WriteLine("Hello");
    }
publicstaticvoidWorld()
    {
Console.WriteLine("World");
    }
  }
classDelegrateEvent  {
//声明委托,event可以让外部无法直接访问这个委托publiceventFuncDelegrateDelegateEvent=null;
  }
}
目录
相关文章
|
2月前
|
开发框架 安全 .NET
C# .NET面试系列三:集合、异常、泛型、LINQ、委托、EF!
<h2>集合、异常、泛型、LINQ、委托、EF! #### 1. IList 接口与 List 的区别是什么? IList 接口和 List 类是C#中集合的两个相关但不同的概念。下面是它们的主要区别: <b>IList 接口</b> IList 接口是C#中定义的一个泛型接口,位于 System.Collections 命名空间。它派生自 ICollection 接口,定义了一个可以通过索引访问的有序集合。 ```c# IList 接口包含一系列索引化的属性和方法,允许按索引访问、插入、移除元素等。 由于是接口,它只定义了成员的契约,而不提供具体的实现。类似于 IEnumera
159 2
|
5月前
|
Java C# C++
【从Java转C#】第八章:委托、lambda、事件
【从Java转C#】第八章:委托、lambda、事件
|
5月前
|
C#
C#中的委托
C#中的委托
20 0
|
6月前
|
存储 开发框架 .NET
c#委托详解
委托是一种能够将方法作为参数传递、存储方法并且调用方法的类型,它可以让我们写出更加灵活和可扩展的代码。委托通常用于回调 (Callback) 机制,比如在事件处理、异步编程、LINQ 查询等场景中常常会使用委托。它可以将方法作为参数传递给其他方法,从而在需要的时候执行该方法。
28 2
|
8月前
|
C# Windows
C#OOP之十一 委托和事件
C#OOP之十一 委托和事件
37 0
|
9月前
|
安全 C#
C#委托事件的区别
C#委托事件的区别
|
10月前
|
C#
C#利用委托实现命令按钮跨窗体控制
C#利用委托实现命令按钮跨窗体控制
80 0
|
10月前
|
C# 容器
C#简单委托示例——让你一看就会的demo
C#简单委托示例——让你一看就会的demo
|
11月前
|
存储 Java C#
【c#入门杂选】重载,继承,委托
【c#入门杂选】重载,继承,委托
76 0