C#委托的妙用

🏷️ 165365比分网 🕒 2025-10-27 18:08:55 👤 admin 👁️ 5573 ❤️ 202
C#委托的妙用

使用C#,但是大多数时候用不上委托,但是委托被讨论得非常多,于是陷入自我怀疑,我是不是太菜了?

我不禁问:为什么要使用委托?

可能试图了解过委托的同学,都被告知委托跟函数指针的关系,又或者被告知一个生活化的举例:委托就是委托别人执行一件事。

可能很多人尝试了解委托的时候都停在这一步,他们了解了委托的写法,寻思:委托也不能简化写法,而且做了和函数同样的事情,为什么要费劲巴拉的使用委托来间接完成函数调用呢?

想到这,我甚至有点生气,为什么他妈的要使用委托?

那就说说为什么要他妈的使用委托!

当你想把方法当参数传给另一个方法

1. 模板方法:Reuse,重复使用,也叫“复用”。代码的复用不但可以提高工作效率,还可以减少 bug 的引入。良好的复用结构是所有优秀软件所追求的共同目标之一。请仔细品味一下示例程序(示例代码来自刘铁锰老师《C#语言入门详解》系列课程):

class Program

{

static void Main(string[] args)

{

//实例化一个ProductFactory,此对象拥有多个成员方法,可被同一种委托类型调用

var productFactory = new ProductFactory();

//定义两个委托

Func func1 = new Func(productFactory.MakePizza);

Func func2 = new Func(productFactory.MakeToyCar);

var wrapFactory = new WrapFactory();

//将委托类型对象作为参数,传给装箱类的构造器

Box box1 = wrapFactory.WrapProduct(func1);

Box box2 = wrapFactory.WrapProduct(func2);

Console.WriteLine(box1.Product.Name);

Console.WriteLine(box2.Product.Name);

}

}

//第一个类:product类,具有一个string类型的属性Name,描述产品的名称

class Product

{

public string Name { get; set; }

}

//第二个类:box类,具有一个Product类型的属性,盒子中有一个product

class Box

{

public Product Product { get; set; }

}

//第三个类:装箱,构造器接收一个参数,参数为一个委托类型,该委托返回一个product类型的对象

//将参数返回的对象,放入box中,完成装箱

class WrapFactory

{

// 模板方法,提高复用性

public Box WrapProduct(Func getProduct)

{

var box = new Box();

Product product = getProduct.Invoke();

box.Product = product;

return box;

}

}

//第四个类:product制造工厂,容纳制造各种product的方法,方法数量可依需求扩展

//但特点是返回值均为Product类型,无参数,即可被同一种委托类型调用

class ProductFactory

{

public Product MakePizza()

{

var product = new Product();

product.Name = "Pizza";

return product;

}

public Product MakeToyCar()

{

var product = new Product();

product.Name = "Toy Car";

return product;

}

}

看完上述程序总结:

我们用了4个类,Product、Box、WrapFactory、ProductFactory,product为操作对象,box为product的装箱容器,WrapFactory专门执行装箱操作,ProductFactory容纳各种product制造函数,此类为可扩展类,异变更。最终在main方法中,在装箱时使用委托作为参数,即 wrapFactory.WrapProduct(func1) 这句代码,我想为什么不直接wrapFactory.WrapProduct(productFactory.MakePizza),不是更方便吗?当我继续往下想,**如果不光是使用参数中的返回值呢,加入作为参数的方法除了返回值,还有out类型的输出参数呢,这时候就不得不使用委托类型作为函数参数了。**而且有没有莫名觉得上面的示例程序结构非常棒棒,当新增一个种类的Product,指需扩展ProductFactory类的成员,并在main方法中增加一个委托,然后装箱即可。这就是我们为什么要使用委托的第一个原因。所以请熟读并模型示例程序!

2. 回调方法:回调方法是通过委托类型参数传入主调方法的被调用方法,主调方法根据自己的逻辑决定是否调用这个方法。请仔细品味一下示例程序(示例代码来自刘铁锰老师《C#语言入门详解》系列课程):

class Program

{

static void Main(string[] args)

{

var productFactory = new ProductFactory();

// Func 前面是传入参数,最后一个是返回值,所以此处以 Product 为返回值

Func func1 = new Func(productFactory.MakePizza);

Func func2 = new Func(productFactory.MakeToyCar);

var wrapFactory = new WrapFactory();

var logger = new Logger();

// Action 只有传入参数,所以此处以 Product 为参数

Action log = new Action(logger.Log);

Box box1 = wrapFactory.WrapProduct(func1, log);

Box box2 = wrapFactory.WrapProduct(func2, log);

Console.WriteLine(box1.Product.Name);

Console.WriteLine(box2.Product.Name);

}

}

class Logger

{

public void Log(Product product)

{

// Now 是带时区的时间,存储到数据库应该用不带时区的时间 UtcNow。

Console.WriteLine("Product '{0}' created 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 getProduct, Action logCallBack)

{

var box = new Box();

Product product = getProduct.Invoke();

// 只 log 价格高于 50 的

if (product.Price >= 50)

{

logCallBack(product);

}

box.Product = product;

return box;

}

}

class ProductFactory

{

public Product MakePizza()

{

var product = new Product

{

Name = "Pizza",

Price = 12

};

return product;

}

public Product MakeToyCar()

{

var product = new Product

{

Name = "Toy Car",

Price = 100

};

return product;

}

}

总结:委托易使用,难精通,慎用委托。

相关文章

办公软件下载哪些网站好
365bet有app吗

办公软件下载哪些网站好

📅 10-14 👁️ 510