C# 委托

委托是函数指针的升级版
一切皆地址
直接调用与间接调用,CPU执行的指令是的

1.actio委托,只能指向没有返回类型的函数。func委托,指向有返回类型的函数。

class Calculator
    {
        public void Report()
        {
            Console.WriteLine("I have 3 methods ");
        }
        public int Add(int a ,int b)
        {
            int result = a + b;
            return result;
        }
        public int Sub(int a ,int b)
        {
            int result = a * b;
            return result;
        }
    }
    //main函数中
    Calculator calculator = new Calculator();
            Action action = new Action(calculator.Report);//只能指向void方法
            calculator.Report();//直接调用
            action.Invoke();//间接调用
            action();
            //前两个为函数的参数类型,目标函数返回的类型
            Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);
            Func<int, int, int> func2 = new Func<int, int, int>(calculator.Sub);
            int x = 100;
            int y = 200;
            int z = 0;

            z = func1(x, y);
            Console.WriteLine(z);
            z = func2(x, y);
            Console.WriteLine(z);

2.自定义委托:返回值得数据类型一直,参数列表在个数和数据类型上一致。

Calc calc1 = new Calc(calculator.Add);
 Calc calc2 = new Calc(calculator.Sub);
Calc calc3 = new Calc(calculator.Mul);
Calc calc4 = new Calc(calculator.Div);

double a = 100;
double b = 200;
double c = 0;
 c = calc1.Invoke(a,b);
Console.WriteLine(c);
c=calc2(a,b);

3.模板方法和回调方法:

using System;

namespace CDelegate
{
    class Program
    {
        public delegate double Calc(double x, double y);
        static void Main(string[] args)
        {
            ProductFactory productFactory = new ProductFactory();
            WrapFactory wrapFactory = new WrapFactory();

            Func<Product> func1 = new Func<Product>(productFactory.MakePuzza);
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
            Logger logger = new Logger();
            Action<Product> log = new Action<Product>(logger.Log);
            Box bos1 = wrapFactory.WrapProduct(func1,log);
            Box bos2 = wrapFactory.WrapProduct(func2,log);

            Console.WriteLine(bos1.Product.Name);
            Console.WriteLine(bos2.Product.Name);

        }

    }
    class Logger
        //记录程序运行状态,回调方法
    {
        public void Log(Product product)
        {
            Console.WriteLine("Product '{0}' create at {1}. Price  is {2}", product.Name, DateTime.UtcNow, product.Price);
        }
    }
    class Product
    {
        public string Name { get; set; }
        public double Price { get; set; }
    }
    class Box
    {
        public Product Product { get; set; }
    }
    class WrapFactory
    {
        public Box WrapProduct(Func<Product> getProduct,Action<Product> logCallback)
        {
            Box box = new Box();
            Product product=getProduct.Invoke();
            box.Product = product;
            if(product.Price >= 50)
            {
                logCallback(product);
            }
            return box;
        }
    }
    class ProductFactory
    {
        public Product MakePuzza()
        {
            Product product = new Product();
            product.Name = "Pizza";
            product.Price = 12;
            return product;
        } 
        public Product MakeToyCar()
        {
            Product product = new Product();
            product.Name = "ToyCar";
            product.Price = 100;
            return product;
        }
    }
}

注意:
1.这是一种方法级别的紧耦合,要慎重
2.使可读性下降,debug难度增加
3.把委托回调,异步调用和多线程纠缠在一起,会让代码变得难以阅读和维护
4.委托使用不当有可能造成内存泄漏和程序性能下降。

4.委托的高级用法
多播委托:用一个委托封装多个委托
action1 += action2;
action2 +=action3;
action1.invoke();
隐式异步调用:BeginInvoke()自动生成一个分支线程,分支线程中调用封装的方法,会隐式异步调用
显示异步调用:
最后,由于委托容易出问题,尽量用接口代替委托

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西柚217

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值