在 C# 中,委托(Delegate)和事件(Event)是两个不同但密切相关的概念,用于实现观察者设计模式。它们之间的主要区别在于使用的上下文和设计用途。
定义: 委托是一个类型,代表一个方法的引用。它允许将方法作为参数传递,存储对方法的引用,并在以后调用该方法。
用途: 委托主要用于实现回调机制,将方法作为参数传递给其他方法,使得这些方法可以在适当的时候调用传递进来的方法。
示例1 :
csharp
public delegate void MyDelegate(string message);
public class MyClass
{
public void DisplayMessage(string message)
{
Console.WriteLine(message);
}
}
// 在其他类中使用委托
MyClass myObject = new MyClass();//类
MyDelegate myDelegate = myObject.DisplayMessage;//myObject.DisplayMessage指向给 委托myDelegate
myDelegate("Hello, Delegate!");//此委托都是传入string message ,也就是需要同类型
示例2 :
csharp
public event EventHandler<EventArgs> StopThreadDownload;
在 C# 中,StopThreadDownload 是一个事件 ,这个事件是由 EventHandler< EventArgs> 类型的委托定义的
StopThreadDownload 事件: 表示一个线程停止下载的事件。它的声明表明它将使用 EventHandler 委托类型,该委托不携带任何额外的参数。
StopThreadDownload(this, new EventArgs());:
this:表示事件的源,即调用事件的对象。
new EventArgs():表示事件的参数,即事件相关的额外信息。在这里,使用 EventArgs 类的实例,该类本身不携带任何额外数据。这是一个通用的标识事件的方式。
这种用法适用于那些不需要携带特定信息的事件。如果事件需要传递额外的信息,可以使用继承自 EventArgs 的自定义类,并在实例化时传递相应的数据。 如
csharp
public class CustomEventArgs : EventArgs
{
public int SomeData { get; }
public CustomEventArgs(int data)
{
SomeData = data;
}
}
可以在事件触发时使用 new CustomEventArgs(someValue) 来传递特定的数据。
示例3 :
假设我们有一个简单的订单系统,其中我们需要计算订单的总金额。我们可以使用委托来实现一个灵活的计算器系统,使得我们可以动态地更改计算逻辑而不影响其他部分的代码。以下是一个使用委托的实际例子
csharp
using System;
// 订单类
public class Order
{
public int OrderId { get; set; }
public decimal Amount { get; set; }
}
// 计算器委托
public delegate decimal CalculateTotalDelegate(Order order);
// 计算器类,负责计算订单的总金额
public class Calculator
{
// 默认的计算逻辑
public decimal DefaultCalculateTotal(Order order)
{
return order.Amount;
}
// 特殊折扣计算逻辑
public decimal DiscountedCalculateTotal(Order order)
{
// 假设有某种折扣逻辑
return order.Amount * 0.9m;
}
}
class Program
{
static void Main()
{
// 创建订单对象
Order order = new Order { OrderId = 1, Amount = 100.00m };
// 创建计算器对象
Calculator calculator = new Calculator();
// 使用默认的计算逻辑
CalculateTotalDelegate calculateDefault = calculator.DefaultCalculateTotal;
decimal defaultTotal = calculateDefault(order);
Console.WriteLine($"Default Total: {defaultTotal:C}");
// 使用特殊折扣的计算逻辑
CalculateTotalDelegate calculateDiscounted = calculator.DiscountedCalculateTotal;
decimal discountedTotal = calculateDiscounted(order);
Console.WriteLine($"Discounted Total: {discountedTotal:C}");
Console.ReadLine();
}
}
建了一个订单对象和一个计算器对象,并使用委托来动态选择计算逻辑。
这样,我们可以在不修改订单类的情况下,根据需要更改计算逻辑。
委托的一个主要用途,即实现灵活的回调机制,允许在运行时更改代码的一部分而不必修改其他部分。在实际应用中,委托常用于事件处理、回调函数、异步编程等场景。
ps:觉得可以留个赞