在 C# 中,委托是一个强大的概念,它允许我们将方法视为值。这意味着我们可以将方法分配给变量,将它们作为参数传递给其他方法,并动态调用它们。在这篇文章中,我将通过示例实现讨论有关委托的简单到高级细节。
委托具有以下几个关键优势:
委托声明定义引用具有特定签名的方法的类型。语法如下:
public delegate return_type delegate_name(parameter\_list);
例如,此委托声明定义一个委托,该委托将字符串作为输入并返回修改后的字符串:StringModifier
public delegate string StringModifier(string inputString);
若要创建委托对象,请使用关键字后跟委托类型和方法引用。方法如下:new
StringModifier modifyString; // Declare a delegate variable
// Assign a method to the delegate
modifyString = (str) => str.ToUpper();
该变量现在包含对 lambda 表达式的引用。modifyString
要调用与委托关联的方法,只需调用委托变量名称,后跟括号即可。这就像调用任何其他方法一样:
string modifiedText = modifyString("Hello World"); // Call the delegate
Console.WriteLine(modifiedText); // Output: HELLO WORLD
委托可以是多播的,这意味着单个委托变量可以包含对具有兼容签名的多个方法的引用。我们可以使用 和 运算符链接方法。链式方法按后进先出 (LIFO) 顺序调用:++=
using System;
class Program
{
public delegate int MathOperation(int a, int b);
public static void Main(string[] args)
{
int Add(int x, int y) => x + y;
int Multiply(int x, int y) => x * y;
MathOperation operation;
operation = Add;
operation += Multiply;
int result = operation(5, 3);
Console.WriteLine(result);
}
}
事件是对象在发生特定情况时引发的通知。其他对象可以使用委托订阅(注册)这些事件,从而允许它们在事件发生时收到通知并执行特定代码:
using System;
public class Button
{
// Define a delegate for the click event
public delegate void ClickedEventHandler(string buttonName);
// Define an event of type ClickedEventHandler
public event ClickedEventHandler Clicked;
public string Name { get; private set; }
public Button(string name)
{
Name = name;
}
// Method to simulate a button click
public void Click()
{
// Check if any event handlers are subscribed
if (Clicked != null)
{
// Invoke all subscribed event handlers and pass the button name
Clicked(Name);
}
}
}
class Program
{
public static void Main(string[] args)
{
// Create two instances of the Button class with different names
Button button1 = new Button("Button 1");
Button button2 = new Button("Button 2");
// Subscribe to the click event of button1
button1.Clicked += (buttonName) => Console.WriteLine(buttonName + " clicked!");
// Subscribe to the click event of button2
button2.Clicked += (buttonName) => Console.WriteLine(buttonName + " clicked!");
// Simulate a click on button1
button1.Click();
// Simulate a click on button2
//button2.Click();
}
}
Lambda 表达式提供了一种以内联方式定义匿名方法的简洁方法。它们可以在委托分配中使用,从而提供更紧凑的方法:
StringModifier modifyString = str => str.ToUpper(); // Lambda expression for uppercase
int operation = (x, y) => x * y + 3; // Lambda for chained math operation
命名空间提供预定义的委托类型,如 和 、SystemFuncAction
Func<int, int, string> formatNumber = (x, y) => $"The number is: {x * y}";
Action logMessage = () => Console.WriteLine("Message logged!");
确保委托和方法之间严格的签名兼容性至关重要。将方法分配给委托时,参数的数量、顺序和类型必须完全匹配。
在处理委托时,方法重载可能会造成混淆。如果类中的多个方法具有相同的名称但不同的参数列表,则编译器将根据委托的签名选择最合适的方法。
**空引用:**调用没有赋值方法(空引用)的委托将抛出 .在调用之前检查 null。NullReferenceException
**方法不兼容:**如果调用的方法的签名与委托的期望不匹配,则可能会发生编译错误或运行时异常。在分配具有不同参数类型的方法时要小心。
我们探讨了有关 Delegates 的核心概念、创建、调用和高级应用程序。记得: