C#中的委托
C# 中的delegate、event、Action、Func都属于委托,只是展现的形式不同而已,无论哪种,其实都可以采用delegat实现
利用委托发布订阅模式可以实现观察者模式 – 传送门
- delegate是很宽泛的,格式内容都不受限,俗话说没有规矩不成方圆,如果一人过于随意,那么他所做的事也规范不到哪去,这就会导致后期的维护很费劲,实际开发中也基本都用后面三种。
区别:
delegate:
至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。
Action:无返回值的泛型委托。
Action: 表示无参,无返回值的委托
Action<int,string> 表示有传入参数int,string无返回值的委托
Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托
Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托
Action至少0个参数,至多16个参数,无返回值。
Func:有返回值的泛型委托
Func<int>
表示无参,返回值为int的委托
Func<object,string,int>
表示传入参数为object, string 返回值为int的委托
Func<object,string,int>
表示传入参数为object, string 返回值为int的委托
Func<T1,T2,T3,int>
表示传入参数为T1,T2,T3(泛型)返回值为int的委托
Func至少0个参数,至多16个参数,根据返回值泛型返回。
必须有返回值,不可void
event:事件,修饰委托
event关键修饰的委托,只能在该类中调用,主要用于封装安全。
用法示例
public class Dog {
public event Action HelloEvent;
public void SayHello()
{
HelloEvent();
}
}
外部代码:
Dog dog = new Dog();
dog.HelloEvent += say1;
dog.SayHello();
static void say1()
{
Console.WriteLine("say1");
}
使用委托可以实现类似多态功能:
static string ToUpper(string str)
{
return str.ToUpper();
}
static string ToLower(string str)
{
return str.ToLower();
}
static string ToStar(string str)
{
return str + "星";
}
static void DealString(Func<string, string> dealFunc,string str)
{
Console.WriteLine(dealFunc(str));
}
DealString(ToUpper, "Abc");
DealString(ToLower, "aBc");
DealString(ToStar, "Abc");
简易示例代码1
using System;
using System.Collections.Generic;
namespace Cat
{
class Cat
{
string _name = "";
public Cat(string name)
{
_name = name;
}
/// <summary>
/// 委托
/// </summary>
public delegate void CatHellEventHandler();
/// <summary>
/// 事件 类型=委托类型 可以使用 += -= 类外不能使用。
/// </summary>
public event CatHellEventHandler CatHell;
/// <summary>
/// 委托对象 类型=委托类型 类外可以使用
/// </summary>
public CatHellEventHandler CatHell1;
public void hell()
{
Console.WriteLine("{0}: i`m coming!", _name);
if(CatHell != null)//event对象-事件为了封装安全,只能在类内使用
{
CatHell();//如果有对象登记事件,则执行!
}
//简化调用 CatHell?为可空类型
// CatHell?.Invoke();
}
}
class Mouse
{
string _name = "";
public Mouse(string name)
{
_name = name;
}
public void Run()
{
Console.WriteLine("{0}: we are runing!", _name);
}
}
class Program
{
static void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));
static void Main(string[] args)
{
//运算符测试 ^ ..
int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int[] subset = numbers[1..(4)];//不包含4范围
Display(subset); // output: 10 20 30
int i = numbers[^1];//最后一个元素
Console.WriteLine(i);
int[] inner = numbers[1..^1];//不包含arr-1=50范围
Display(inner); // output: 10 20 30 40
string line = "one two three";
Range endIndices = ^5..^0;
string end = line[endIndices];
Console.WriteLine(end); // output: three
Console.WriteLine("Hello World!");
Cat cat = new Cat("tom");
Mouse mouse1 = new Mouse("jerry");
Mouse mouse2 = new Mouse("jerry1");
//事件对象CatHell 类内调用
//只能在类内使用,类外只能出现在 += -= 的左边
cat.CatHell += new Cat.CatHellEventHandler(mouse1.Run);
cat.hell();
//cat.CatHell(); 无法调用
//委托对象CatHell1 类外调用
cat.CatHell1 += new Cat.CatHellEventHandler(mouse1.Run);
cat.CatHell1 += new Cat.CatHellEventHandler(mouse2.Run);
//调用方法1
cat.CatHell1.Invoke();
//调用方法2
cat.CatHell1();
Console.ReadLine();
}
}
}