C#委托的理解

以苹果手机举例子
设计 --> 生产 --> 销售
生产就可以变成委托:设计 --> 委托 --> 销售
这样的好处就是通过委托会变得更灵活,如果出现比富士康更好的代工厂,可以直接更换富士康。

定义委托

  • delegate
  • [访问修辞] delegate 返回类型 委托名(参数列表)

实例化委托

  • 委托类型 委托变量 = new 委托名(方法名)
  • 委托类型 委托变量 = 方法名

使用委托

  • 委托引用名(实参列表)
  • 委托引用?.Invoke(参数)
//委托的实际运用
//形参为委托类型
static void Test(Cal f)
{
	Console.Write("请输入x:");
	double x = Convert.ToDouble(Console.ReadLine());
	Console.Write("请输入y:");
	double y = Convert.ToDouble(Console.ReadLine());
	//委托方法工作,怎么工作由具体委托决定
	double result = f(x,y);
	Console.WriteLine("X:{0}与Y:{1}委托方法计算结果为:{2}",x,y,result);
}

//定义委托  这个委托还可以写入下面的Program类里
public delegate double Cal(double x,double y)

internal class Program
{
	static double Add(double x,double y)
	{
		return x+y;
	}
	static double Dec(double x,double y)
	{
		return x-y;
	}
	static void Main(string[] args)
	{
	/* 写法1
		Cal cal = new Cal(Add);		//找到委托对象
		doubel result = cal(6,8);
		Console.WriteLine($"委托Add计算结果为:{result}");
	*/
	/* 写法2
		Cal cal = Dec;
		Test(cal);
	*/
	/* 写法3
		Test(new Cal(Add));
	*/
		Test(Dec);
		Console.ReadKey();
	}
}

委托是一种引用类型的变量,用于存储某个方法的引用地址
定义格式

  • public delegate 返回值类型 委托类型的名字(参数类型1 参数名字,参数类型2 参数名字,…)

委托存在的意义

  • 回调方法:当某个任务执行完毕后或者某事件触发后,调用的方法
// 1 场面上所有的按钮,都是当前Button类实例化的对象
    // 2 每个按钮被点击后,发生的事情都不一样
    // 3 每个按钮点击后,发生的事情由外界决定
    class Button
    {
        // 1 声明一个点击信息响应的方法类型签名(委托)
        public delegate void OnClickDelegat();

        // 2 声明(创建)一个OnClickDelegate类型的委托(分配地址)
        public OnClickDelegat onclick = null;

        // 3 在点击事件触发后,调用onclick委托存储的方法
        //模拟点击
        public void Click()
        {
            Console.WriteLine("按钮被点击了");
            if (onclick != null)
                onclick();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Button gameStartButton = new Button();
            gameStartButton.onclick = new Button.OnClickDelegat(OnGameStart);

            gameStartButton.Click();
            Console.ReadKey();
        }

        //点击了游戏开始按钮触发的方法
        static public void OnGameStart()
        {
            Console.WriteLine("游戏开始");
        }
    }

用类里的方法(实现结果与上面代码一致)

 // 1 场面上所有的按钮,都是当前Button类实例化的对象
    // 2 每个按钮被点击后,发生的事情都不一样
    // 3 每个按钮点击后,发生的事情由外界决定
    class Button
    {
        // 1 声明一个点击信息响应的方法类型签名(委托)
        public delegate void OnClickDelegat();

        // 2 声明一个OnClickDelegate类型的委托
        public OnClickDelegat onclick = null;

        // 3 在点击事件触发后,调用onclick委托存储的方法
        //模拟点击
        public void Click()
        {
            Console.WriteLine("按钮被点击了");
            if (onclick != null)
                onclick();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            GameController gameController = new GameController();

            // 开始游戏按钮
            Button gameStartButton = new Button();
            gameStartButton.onclick = new Button.OnClickDelegat(gameController.OnGameStart);

            gameStartButton.Click();


            Button friendButton = new Button();
            friendButton.onclick = new Button.OnClickDelegat(gameController.OnFriend);

            friendButton.Click();



            Console.ReadKey();
        }

        //点击了游戏开始按钮触发的方法
        //static public void OnGameStart()
        //{
        //    Console.WriteLine("游戏开始");
        //}

        //static public void OnFriend()
        //{
        //    Console.WriteLine("分享给好友");
        //}
    }

创建了一个类

internal class GameController
    {
        public GameController() { }

        //游戏开始的方法
        public void OnGameStart()
        {
            Console.WriteLine("游戏开始 --- 这是类里的方法");
        }

        //分享给好友
        public void OnFriend()
        {
            Console.WriteLine("分享给好友 --- 这是类里的方法");
        }
    }

委托存在的意义二次思考

  • 需求:把Button类,写成一个独立的C#文件,然后可以在其他项目中使用



不用Delegate

class StartButton
{
	public void OnClick()
	{
		Game game = new Ganme();
		GameMap map = new GameMap();
	}
	......
}

使用Delegate

class Button
{
	public delegate void OnClickDelegate();
	......
	public OnClickDelegate OnClick = null;
	......
	public void Click(){ OnClick();}

区别:使用delegate后,代码可以直接给新项目使用。但是不用delegate的代码里面会有Game、GameMap等其他新项目没有的类


委托的多播

  • 多播:一个主委托对象可以容纳多个其他的子委托对象,当调用主委托对象,会将所有子委托全部按序运行
class Program
    {
        public delegate int CalculateDelegate(int a, int b);

        public static int Add(int a, int b)
        {
            System.Console.WriteLine(a + b);
            return a + b;
        }

        public static int Multiply(int a, int b)
        {
            System.Console.WriteLine(a * b);
            return a * b;
        }


        static void Main(string[] args)
        {
            CalculateDelegate cal0 = new CalculateDelegate(Add);
            CalculateDelegate cal1 = new CalculateDelegate(Multiply);

            //多播方式1
            //CalculateDelegate cal = cal0 + cal1;


            //多播方式2
            //CalculateDelegate cal = null;
            //cal += cal0;
            //cal += cal1;

            //cal(1, 3);

            cal0 += cal1;
            cal0(1, 3);
            Console.Read();

        }

    }

泛型委托的好处:简化委托的使用
委托的使用步骤:
1、定义委托(泛型委托要解决的问题是定义委托,可以不用自己定义委托)
2、实例化委托
3、执行委托

Action委托

  • public delegate void Action();
  • public degegate void Action(T obj);

Func< TResult>委托

  • public delegate TResult Func< out TResult>();
  • public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1,T2 arg2);
internal class Program
{
	//第一个函数
	static void SayHi()
	{
		Console.WriteLine("你好");
	}
	
	//第二个函数
	static void SayHi(string msg)
	{
		Console.WriteLine(msg);
	}
	
	//第三个函数
	static double Add(double x,double y)
	{
		return x + y;
	}

	//第四个函数
	static void Mul(demical x,int y)
	{
		return x * y;
	}
	
	static void Main(string[] args)
	{
		//此时指向第一个函数
		Action action = SayHi;
		action();
	
		//此时指向第二个函数
		Action<string> action = SayHi;
		action("世界");
		
		//此时指向第三个函数
		Func<double,double,double> func = new func<double,double,double>(Add);
		double result = func(1.2,2.2);
		Console.WriteLine(result);

		//此时指向第四个函数
		Func<decimal,int,decimal> func = Mul;		//第三个类型是返回值得类型
		decimal result = func(1.2m,2.2);
		Console.WriteLine(result);

		Console.ReadKey();
	}
}

自定义泛型委托(泛型的好处是可以更多的选择,例如int,double)

namespace Combine{
	class Program{
		static void Main(string[] args)
		{
			MyDele<int> deleAdd = new MyDele<int>(Add);
			int res = deleAdd(100,200);
			Console.WriteLine(res);

			MyDele<double> deleMul = new MyDele<double>(Mul);
			double mulRes = deleMul(3.0,4.0);
			Console.WriteLine(mulRes);
		}
	
		static int Add(int x,int y)
		{
			return x + y;
		}

		static double Mul(double x,double y)
		{
			return x * y;
		}
	}

	delegate T MyDele<T>(T a,T b);
} 

总结

  • 1、委托其实就是方法的引用,其声明格式为;
    • public delegate 返回值类型 委托类型名字 {参数列表…};
    • public 委托类型名字 委托名字;
  • 2、委托用在某个事务完毕后回调或者响应某个事件
  • 3、一个委托可以包含多个子委托,从而实现广播调用
    4、具体使用场景:有一个按钮,每次点击执行不同方法(例如变换页面颜色)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值