C#的内置泛型委托
简介
内置泛型委托是编程语言提供的预定义委托类型。内置的泛型委托有 Func < TResult >、Action、Predicate< T >、Comparison< T > 和 Converter<TInput, TOutput>。
使用泛型委托的好处:
- 无需显式声明自定义的委托。
- 灵活性且简洁。
使用委托的缺点:
- 委托实例本身是有成本的,并且委托调用通常比直接方法调用慢。因此,在高性能场景中,需要谨慎使用委托。
优势举例对比说明
委托定义的简洁性:
- 一般的委托定义方式:需要先定义一个委托,再声明创建一个委托实例。
class Program
{
// 定义一个委托
public delegate void MyDelegate(string message);
static void Main(string[] args)
{
// 创建委托实例并绑定到方法
MyDelegate myDelegate = new MyDelegate(DisplayMessage);
// 调用委托
myDelegate?.Invoke("Hello from Delegate Invoke!");
}
// 与委托和事件关联的方法
static void DisplayMessage(string message)
{
Console.WriteLine(message);
}
}
- 使用泛型委托的方式:可以直接省略掉委托的定义,直接声明。
class Program
{
static void Main(string[] args)
{
// 定义内置泛型委托实例并绑定到方法
Action<string> myDelegate = DisplayMessage;
// 调用委托
myDelegate?.Invoke("Hello from Delegate Invoke!");
}
// 与委托和事件关联的方法
static void DisplayMessage(string message)
{
Console.WriteLine(message);
}
}
- 结合匿名表达式的方式:代码更加简洁
class Program
{
static void Main(string[] args)
{
// 定义内置泛型委托实例并使用Lambda表达式绑定到方法
Action<string> myDelegate = ((message) => { Console.WriteLine(message); });
// 调用委托
myDelegate?.Invoke("Hello from Delegate Invoke!");
}
}
在集合类中应用的灵活性:
- 一般做法:若要在List < T>中找出某个值,需要遍历List中的每一个成员进行比较。
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
string firstMatch = "";
// 使用forech遍历每一个成员,查找以'A'开头成员的第一个匹配项
foreach (var name in names)
{
if (name.StartsWith("A"))
{
firstMatch = name;
break;
}
}
Console.WriteLine(firstMatch); // 输出: Alice
}
}
- 使用泛型委托:直接利用List.Find(Predicate match)中的泛型委托,就可以一句话实现。
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
// 使用Predicate<T>委托来定义搜索条件:查找以'A'开头的名字
// 使用Find方法查找第一个匹配项
string firstMatch = names.Find(name => name.StartsWith("A"));
Console.WriteLine(firstMatch); // 输出: Alice
}
}
泛型委托的详细用法说明
Func < TResult > 委托
Func < TResult > 委托用于表示接受任意数量和类型参数的方法,并返回一个结果。
可以有0到16个输入参数,并有一个返回值。
// 定义
public delegate TResult Func<in T1, in T2, ..., out TResult>(T1 arg1, T2 arg2, ...);
//使用
Func<int, int, int> add = (a, b) => a + b;
int result = add(3, 4); // result is 7
Action 委托
Action 委托用于表示接受任意数量和类型参数的方法,但不返回任何值(即返回 void)。
可以有0到16个输入参数,但没有返回值。
//定义
public delegate void Action<in T1, in T2, ...>(T1 arg1, T2 arg2, ...);
//使用
Action<string> displayMessage = message => Console.WriteLine(message);
displayMessage("Hello, World!"); // Outputs "Hello, World!"
Predicate< T >
Predicate< T > 委托代表一个返回布尔值的方法,该方法接受一个输入参数并返回一个bool值。它通常用于测试某个条件是否满足。
//在这个例子中,isEven委托表示该数字是否为偶数。
Predicate<int> isEven = num => num % 2 == 0;
bool is4Even = isEven(4); // is4Even is true
bool is5Even = isEven(5); // is5Even is false
Comparison < T >
Comparison < T > 委托代表一个比较两个对象的方法,并返回一个整数,表示这两个对象的相对顺序。
//在这个例子中,compareStrings委托接受两个string类型的参数,并返回一个整数,表示这两个字符串在字典序中的相对位置
Comparison<string> compareStrings = (x, y) => x.CompareTo(y);
int result = compareStrings("apple", "banana"); // result is less than 0 because "apple" comes before "banana" in lexicographical order
Converter < TInput, TOutput >
Converter<TInput, TOutput> 委托代表一个将一种类型转换为另一种类型的方法。
//在这个例子中,intToString委托,接受一个int类型的参数,并返回一个表示该整数的string。
Converter<int, string> intToString = i => i.ToString();
string numberAsString = intToString(123); // numberAsString is "123"
匿名委托和 Lambda 表达式
匿名委托和 Lambda 表达式虽然它们不是委托类型,但经常用于委托的实例化。匿名委托是没有名称的方法,而 Lambda 表达式是一种更简洁的匿名函数语法。它们都可以用来创建委托实例。
—多学习多交流—多多指教