C# 笔记 Func<TResult> 委托、Action<T> 委托
https://blog.csdn.net/wanglui1990/article/details/79303894
Func<ΤResult> 委托:代理(delegate)一个返回类型为「由参数指定的类型的值(TResul)」 的无参方法。使用 Func<ΤResult> 委托,无需显式定义一个委托与方法的关联。
Func<ΤResult>原型:
public delegate TResult Func<out TResult>()
- 1
Func<ΤResult>示例:
主方法
namespace 异步操作
{
class Program
{
static void Main(string[] args)
{
FuncDelegate fDel = new FuncDelegate();
fDel.ExplicitlyDeclaresTest();
fDel.SimplifiesByFuncT();
fDel.SimplifiesByFuncTAndAnonymousMethod();
fDel.SimplifiesByFuncTAndLambda();
fDel.ExtendFuncT();
ActionTtest aDel = new ActionTtest();
aDel.ExplicitlyDeclaresActionTTest();
aDel.SimplifiesByActionT();
aDel.SimplifiesByActionTAndAnonymousMethod();
aDel.SimplifiesByActionTAndLambda();
aDel.ExtendActionT();
Console.Read();
}
}
}
示例代码:
namespace 异步操作
{
//Func<TResult>() 委托:返回类型为TResult的无参方法。
//Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> 委托:返回TResult类型,带9个参数的方法。
//当您使用 Func<TResult> 委托时,您无需显式定义一个委托,用于封装无参数的方法。 例如,下面的代码显式声明的委托名为 WriteMethod 和分配的引用 OutputTarget.SendToFile 实例到其委托实例的方法。
//https://msdn.microsoft.com/zh-cn/library/bb534960(v=vs.110).aspx
public class OutputTarget
{
public bool SendToFile()
{
try
{
string fn = Path.GetTempFileName();
StreamWriter sw = new StreamWriter(fn);
sw.WriteLine("Hello, World!");
sw.Close();
return true;
}
catch
{
return false;
}
}
}
delegate bool WriteMethod();
class FuncDelegate
{
//显式声明委托与方法的关联
public void ExplicitlyDeclaresTest()
{
OutputTarget output = new OutputTarget();
WriteMethod methodCall = output.SendToFile;//建立委托与方法的关联。
if (methodCall())//执行此行时,跳转去执行绑定的方法SendToFile()
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
//使用Func<TResult>简化 委托与方法的关联
public void SimplifiesByFuncT()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = output.SendToFile;//简化关联
if (methodCall())//执行此行时,跳转去执行绑定的方法SendToFile()
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
//使用Func<TResult>和匿名方法简化 委托与方法的关联
public void SimplifiesByFuncTAndAnonymousMethod()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = delegate () { return output.SendToFile(); };//匿名方法简化Func<T>与方法的关联
if (methodCall())//执行此行时,跳转去执行 绑定的匿名方法() { return output.SendToFile(); },执行完后返回
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
//使用Func<TResult>和Lambda、匿名方法简化 委托与方法的关联
public void SimplifiesByFuncTAndLambda()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = () => output.SendToFile();//Lambda、匿名方法 简化Func<T>与方法的关联
if (methodCall()) // 执行此行时,跳转去执行 绑定的() => output.SendToFile(),执行完后返回
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
//扩展:以Funct<T>未参数类型传递。
public void ExtendFuncT()
{
//():匿名无参方法。() =>方法名,指派匿名无参方法去执行另外一个方法。
LazyValue<int> lazyOne = new LazyValue<int>(() => ExpensiveOne());//匿名无参方法被指派去执行ExpensiveOne
LazyValue<long> lazyTwo = new LazyValue<long>(() => ExpensiveTwo("apple"));//匿名无参方法被指派去执行ExpensiveTwo
Console.WriteLine("LazyValue objects have been created.");
//泛型类别根据 关联的委托与方法 取值。
Console.WriteLine(lazyOne.Value);//跳转到() => ExpensiveOne(),执行LazyValue<T>.Value的取值,然后显示结果。
Console.WriteLine(lazyTwo.Value);//跳转到() => ExpensiveTwo("apple"),执行LazyValue<T>.Value的取值,然后显示结果。
}
//无参测试方法
static int ExpensiveOne()
{
Console.WriteLine("\nExpensiveOne() is executing.");
return 1;
}
//计算字串长度
static long ExpensiveTwo(string input)
{
Console.WriteLine("\nExpensiveTwo() is executing.");
return (long)input.Length;
}
}
//扩展:自定义泛型类别LazyValue T,以Funct<T>为参数类型传递。
class LazyValue<T> where T : struct
{
private T? val;//或 Nullable<T> val; //标记返回类型T,同时用于保存Func<T>委托的方法的返回值
private Func<T> getValue; //返回类型为T的委托
// 构造。参数Funct<T>类型:传入的参数为返回类型为TResult(任何类型)的无参方法。
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
val = getValue();//取得委托方法的返回值。
return (T)val; //强制抓换委托方法返回值类型。
}
}
}
}
Action<Τ> 委托:代理(delegate)无返回值 参数类型为 T 的无参方法。使用 Action<Τ> 委托,无需显式定义一个委托与方法的关联。
Action<Τ>原型:
public delegate void Action<in T>(
T obj
)
Action<Τ>示例代码:
namespace 异步操作
{
delegate void DisplayMessage(string message);//委托:一个string类型参数、无返回值的方法
public class ActionTOutputTarget
{
public void ShowWindowsMessage(string message)
{
Console.WriteLine(message);
}
}
class ActionTtest
{
//显式声明委托与方法的关联
public void ExplicitlyDeclaresActionTTest()
{
DisplayMessage methodCall;//委托名methodCall
ActionTOutputTarget output = new ActionTOutputTarget();
if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入
methodCall = output.ShowWindowsMessage;
else
methodCall = Console.WriteLine;
methodCall("Hello, World!"); //执行带参方法。
}
//使用Action<T>简化 委托与方法的关联
public void SimplifiesByActionT()
{
ActionTOutputTarget output = new ActionTOutputTarget();
Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法
if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入
methodCall = output.ShowWindowsMessage;
else
methodCall = Console.WriteLine;
methodCall("Hello, World!"); //执行带参方法。
}
//使用Action<T>和匿名方法简化 委托与方法的关联
public void SimplifiesByActionTAndAnonymousMethod()
{
ActionTOutputTarget output = new ActionTOutputTarget();
Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法
if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入
methodCall = delegate (string s) { output.ShowWindowsMessage(s); };//匿名方法参数签名(string s)
else
methodCall = delegate (string s) { Console.WriteLine(s); };
methodCall("Hello, World!"); //执行带参方法。
}
//使用Action<T>和Lambda、匿名方法简化 委托与方法的关联
public void SimplifiesByActionTAndLambda()
{
ActionTOutputTarget output = new ActionTOutputTarget();
Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法
if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入
methodCall = (string s)=> { output.ShowWindowsMessage(s); };//Lambda参数s传递给匿名方法,方法体{ output.ShowWindowsMessage(s); }
else
methodCall = (string s)=> { Console.WriteLine(s); };
methodCall("Hello, World!"); //执行带参方法。
}
//扩展:以Action<T>为参数类型传递。
public void ExtendActionT()
{
List<String> names = new List<String>();
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");
Console.WriteLine("==========List<string>.ForEach(Action<T> action>=======");
//以Action<T>类型为参数 List<string> ForEach:public void ForEach(Action<T> action);
names.ForEach(Print);
Console.WriteLine("==========匿名方法 delegate(string name)={Console.WriteLine();}=======");
// 匿名方法
names.ForEach(delegate (string name)
{
Console.WriteLine("console:"+name);
});
}
private void Print(string s)
{
Console.WriteLine("Print:"+s);
}
}
}
总结:以后如果要新建委托与方法关联,可简化代码如下(使用匿名方法+Lambda+Func<Τ>)。
//Func<bool> methodCall = () => output.SendToFile()
//methodCall()//执行 关联的方法()
Func<关联方法返回类型> methodCall = () => 关联的方法()//传递匿名无参方法() 并与想要执行方法关联(=>),可关联方法可任意参数,但必须有返回类型(无返回值的用Action<T>)。
methodCall()。//执行 关联的方法
C# 笔记 Func<TResult> 委托、Action<T> 委托的更多相关文章
- Func<T>与Action<T>委托泛型介绍:转
.Net 3.5之后,微软推出了Func<T>与Action<T>泛型委托.进一步简化了委托的定义. Action<T>委托主要的表现形式如下: public de ...
- Func<T>与Action<T>委托泛型介绍
.Net 3.5之后,微软推出了Func<T>与Action<T>泛型委托.进一步简化了委托的定义. Action<T>委托主要的表现形式如下: public de ...
- C# 委托 (一)—— 委托、 泛型委托与Lambda表达式
C# 委托 (一)—— 委托. 泛型委托与Lambda表达式 2018年08月19日 20:46:47 wnvalentin 阅读数 2992 版权声明:此文乃博主之原创.鄙人才疏,望大侠斧正.此 ...
- [C#学习笔记]Func委托与Action委托
学习一项新知识的时候,最好的方法就是去实践它. 前言 <CLR via C#>这本神书真的是太有意思了!好的我的前言就是这个. Fun 如果要用有输入参数,有返回值的委托,那么Func委托 ...
- C#学习笔记:泛型委托Action<T>和Fun<TResult>
转自:http://www.cnblogs.com/Joetao/articles/2094271.html 本节学习了泛型委托Action<T>和Fun<TResult>两类 ...
- C#委托Action、Action<T>、Func<T>、Predicate<T>
CLR环境中给我们内置了几个常用委托Action. Action<T>.Func<T>.Predicate<T>,一般我们要用到委托的时候,尽量不要自己再定义一 个 ...
- C#中常见的委托(Func委托、Action委托、Predicate委托)
今天我要说的是C#中的三种委托方式:Func委托,Action委托,Predicate委托以及这三种委托的常见使用场景. Func,Action,Predicate全面解析 首先来说明Func委托,通 ...
- [转]C#委托Action、Action<T>、Func<T>、Predicate<T>
CLR环境中给我们内置了几个常用委托Action. Action<T>.Func<T>.Predicate<T>,一般我们要用到委托的时候,尽量不要自己再定义一 个 ...
- C#委托Action、Action<T>、Func<T>、Predicate<T>系统自带的委托
C#委托Action.Action<T>.Func<T>.Predicate<T> CLR环境中给我们内置了几个常用委托Action. Action<T& ...
随机推荐
- Android 应用开发实例之情景模式
2013-07-01 Android 应用开发实例 1. 情景模式 使用TabHost来实现主界面的布局. 设置一组RadioButton来切换不同的情景模式. 对比普通情景模式,定时情景模式需要加上 ...
- CentOS6.5卸载默认安装的mysql5.1,并安装mysql5.5(亲测有效)
感谢链接:https://jingyan.baidu.com/article/922554465e471a851648f4ed.html 指导. 1.安装前:CentOS6.5 yum 安装MySQ ...
- 【CentOS6.5】安装之DNS配置错误,yum install 软件报错:ERROR 6或者56错误提示”could not retrieve mirrorlist http://mirrorlist.centos.org ***”
刚安装完CentOS,使用yum命令安装一些常用的软件,使用如下命令:yum grouplist | more. 提示如下错误信息: Loaded plugins: fastestmirror Set ...
- 【LeetCode】78. Subsets (2 solutions)
Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset ...
- 执行 maven 命令 报错Unable to add module to the current project as it is not of packaging type 'pom'[转]
今天学习在本地搭建Maven工程时,执行了mvn archetype:generate 命令,报错. Unable to create project from archetype [org.apac ...
- 流类库继承体系(IO流,文件流,串流)和 字符串流的基本操作
一.IO.流 数据的输入和输出(input/output简写为I/O) 对标准输入设备和标准输出设备的输入输出简称为标准I/O 对在外存磁盘上文件的输入输出简称为文件I/O 对内存中指定的字符串存储空 ...
- ISP图像质量调节介绍
ISP(Image Signal Processor),即图像处理,主要作用是对前端图像传感器输出的信号做后期处理,主要功能有线性纠正.噪声去除.坏点去除.内插.白平衡.自己主动曝光控制等.依赖于IS ...
- 用Visual studio2012在Windows8上开发内核驱动监视进程创建
在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...
- 基于Bootstrap的Asp.net Mvc 分页的实现(转)
最近写了一个mvc 的 分页,样式是基于 bootstrap 的 ,提供查询条件,不过可以自己写样式根据个人的喜好,以此分享一下.首先新建一个Mvc 项目,既然是分页就需要一些数据,我这 边是模拟了一 ...
- 各种Map的区别,想在Map放入自定义顺序的键值对
今天做统计时需要对X轴的地区按照地区代码(areaCode)进行排序,由于在构建XMLData使用的map来进行数据统计的,所以在统计过程中就需要对map进行排序. 一.简单介绍Map 在讲解Map排 ...