首页 > 编程语言 >C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法

C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法

时间:2022-11-29 20:39:21浏览次数:30  
标签:Predicate string 委托 C# void writer System static Action


C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托是保存对某个方法引用的一种引用类型变量。

若要引用的方法,具有两个参数没有返回值,使用Action<T1, T2>委托,则不需要显式定义委托。Action<T>委托还有很多重载,根据参数的个数,选择不同的方法重载。

C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法_Predicate

若要引用的方法,具有两个参数并返回一个值,使用泛型Func<T1, T2, TResult>委托,则不需要显式定义委托。Func<T>委托还有很多重载,根据参数的个数,选择不同的方法重载。

C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法_Delegate_02

一、使用delegate定义没有返回值的委托:

using System;
using System.IO;

delegate void ConcatStrings(string string1, string string2);

public class TestDelegate
{
public static void Main()
{
string message1 = "The first line of a message.";
string message2 = "The second line of a message.";
ConcatStrings concat;

if (Environment.GetCommandLineArgs().Length > 1)
concat = WriteToFile;
else
concat = WriteToConsole;

concat(message1, message2);
}

private static void WriteToConsole(string string1, string string2)
{
Console.WriteLine("{0}\n{1}", string1, string2);
}

private static void WriteToFile(string string1, string string2)
{
StreamWriter writer = null;
try
{
writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false);
writer.WriteLine("{0}\n{1}", string1, string2);
}
catch
{
Console.WriteLine("File write operation failed...");
}
finally
{
if (writer != null) writer.Close();
}
}
}

使用Action<T1, T2>委托,则不需要显式定义委托:

using System;
using System.IO;

public class TestAction2
{
public static void Main()
{
string message1 = "The first line of a message.";
string message2 = "The second line of a message.";
Action<string, string> concat;

if (Environment.GetCommandLineArgs().Length > 1)
concat = WriteToFile;
else
concat = WriteToConsole;

concat(message1, message2);
}

private static void WriteToConsole(string string1, string string2)
{
Console.WriteLine("{0}\n{1}", string1, string2);
}

private static void WriteToFile(string string1, string string2)
{
StreamWriter writer = null;
try
{
writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false);
writer.WriteLine("{0}\n{1}", string1, string2);
}
catch
{
Console.WriteLine("File write operation failed...");
}
finally
{
if (writer != null) writer.Close();
}
}
}

二、使用delegate定义有返回值的委托:

using System;

delegate string[] ExtractMethod(string stringToManipulate, int maximum);

public class DelegateExample
{
public static void Main()
{
ExtractMethod extractMeth = ExtractWords;
string title = "The Scarlet Letter";
foreach (string word in extractMeth(title, 5))
Console.WriteLine(word);
}

private static string[] ExtractWords(string phrase, int limit)
{
char[] delimiters = new char[] {' '};
if (limit > 0)
return phrase.Split(delimiters, limit);
else
return phrase.Split(delimiters);
}
}

使用泛型Func<T1, T2, TResult>委托, 则不需要显式定义委托:

using System;

public class GenericFunc
{
public static void Main()
{
Func<string, int, string[]> extractMethod = ExtractWords;
string title = "The Scarlet Letter";
foreach (string word in extractMethod(title, 5))
Console.WriteLine(word);
}

private static string[] ExtractWords(string phrase, int limit)
{
char[] delimiters = new char[] {' '};
if (limit > 0)
return phrase.Split(delimiters, limit);
else
return phrase.Split(delimiters);
}
}

使用Action<T1, T2>委托和Func<T1, T2, TResult>委托,可以简化代码,让逻辑更清晰。

 

Predicate<T>委托

Predicate泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。

先来看一下Array.FindAll

// 摘要:
// 检索与指定谓词定义的条件匹配的所有元素。
//
// 参数:
// array:
// 要搜索的从零开始的一维 System.Array。
//
// match:
// System.Predicate`1,定义要搜索元素的条件。
//
// 类型参数:
// T:
// 数组元素的类型。
//
// 返回结果:
// 如果找到一个 System.Array,其中所有元素均与指定谓词定义的条件匹配,
// 则为该数组;否则为一个空 System.Array。
//
// 异常:
// T:System.ArgumentNullException:
// array 为 null。 - 或 - match 为 null。
public static T[] FindAll<T>(T[] array, Predicate<T> match);

FindAll两个参数第一个就是数组(字符串数组,int数组等等),第二个就是委托Predicate有一个参数。

第一种方式:通过一个lambda表达式传递参数

string[] arrayString = new string[]{"One","Two","Three","Four","Fice","Six","Seven","Eight","Nine","Ten"};

string[] arrayResult = Array.FindAll(arrayString, (c) => c.Length > 3);

第二种方式:通过委托进行传递方法的方式

public void PredicateArrayTest()
{
string[] arrayString = new string[]{"One","Two","Three","Four","Fice","Six",
"Seven","Eight","Nine","Ten"};

string[] arrayResult = Array.FindAll(arrayString, (c) => c.Length > 3);
string[] arrayResultMethod = Array.FindAll(arrayString, GetString);
}
private bool GetString(string item)
{
if (item.Length > 3)
{
return true;
}
return false;
}

第三种方式:通过匿名代理

string[] arrayResultDelegate = Array.FindAll(arrayString, delegate(string c) { return c.Length > 3; });

对List的实现其实和Array的实现原理几乎完全一样。

标签:Predicate,string,委托,C#,void,writer,System,static,Action
From: https://blog.51cto.com/u_6871414/5896967

相关文章

  • Unity--Physics.OverlapSphere的参数LayerMask和GameObject的layer
    Layer介绍:Unity中是用int32来表示32个Layer层。int32表示二进制一共有32位(0—31)在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共......
  • C#数据结构--Dictionary、HashTable、List、HashSet区别
    在.Net  模仿java的过程中,抛弃了HashMap,所以我们今天分析下Dictionary、HashTable、HashSet区别。处理碰撞,即碰撞到同一个Bucket槽上:Hashtable和Dictionary从数据结构上......
  • C#设计模式读书笔记之设计模式的设计原则
    设计模式的设计原则:(重要性从上往下排列)开闭原则:对扩展开放,对修改关闭依赖倒转原则:高层模块不应该依赖底层模块,它们都应该依赖抽象;要针对抽象层编程,而不要针对具体类编程。......
  • Unity-Animator Override Controller
    AnimatorOverrideController是一种资产类型,允许您扩展现有的AnimatorController,替换使用的特定动画,但保留原始结构,参数和逻辑。允许您创建相同基本状态机的多个变体,但每......
  • ClassLoader
    ClassLoader:用来加载Class的。负责将Class的字节码形式转换成内存形式的Class对象。字节码可以来自于磁盘文件*.class,也可以是jar包里的*.class,也可以来自远程......
  • C++函数编译原理和成员函数的实现
    对象的内存中只保留了成员变量,除此之外没有任何其他信息,程序运行时不知道stu的类型为Student,也不知道它还有四个成员函数setname()、setage()、setscore()、show(),C++......
  • sizeof(struct)和sizeof(union)的结果分析及其原因
    一个错误有的时候,在脑海中停顿了很久的“显而易见”的东西,其实根本上就是错误的。就拿下面的问题来看:structT{charch;inti;};使用sizeof(T),将得到什么样的答案呢......
  • leetcode 1976.到达目的地的方案数
    问题描述:你在一个城市里,城市由n 个路口组成,路口编号为 0 到 n-1 ,某些路口之间有双向 道路。输入保证你可以从任意路口出发到达其他任意路口,且任意两个路口之间......
  • C++多态性
    虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。虚函数    是在基类中使用关键字virtual声明的函数。在派生类中重......
  • C#数据结构-Dictionary实现
    在看过一篇大神写的​​《带你看懂Dictionary的内部实现》​​,对Dictionary的内部实现有了一个清晰的了解,但纸上得来终觉浅,作为程序员,还是自己调试一下代码,记忆更深刻,为此专......