C# Func<>托付
曾经我们为了可以调用一个方法。必须比照这种方法定义一个对应的delegate.
原先我们定义delegate
// 托付声明 -- 定义一个签名:
delegate double MathAction(double num);
class DelegateTest
{
// 符合托付声明的常规方法
static double Double(double input)
{
return input * 2;
} static void Main()
{
原版: // 使用一个命名方法实例化托付类型
MathAction ma = Double; // 调用托付实例
double multByTwo = ma(4.5);
Console.WriteLine(multByTwo); 简化版1: // 再用匿名方法来实例化托付类型
MathAction ma2 = delegate(double input)
{
return input * input;
}; double square = ma2(5);
Console.WriteLine(square); 简化版2: // 最后用Lambda表达式来实例化托付类型
MathAction ma3 = s => s * s * s;
double cube = ma3(4.375); Console.WriteLine(cube);
}
}
这个能否有更好的实现办法呢?
答案是:肯定有了.也就是有通用的delegate了。
在.NETFramework
3.5中。提供了两类通用的delegate。
假设方法有返回值,则使用Func,或者Func<>
假设方法没有返回值,则使用Action,或者Action<>
Func<T,TR>(T arg)
T
此托付封装的方法的參数类型。
TR
此托付封装的方法的返回值类型。
參数
- arg
- 类型 T
- 此托付封装的方法的參数。
在使用 Func<T,TResult>托付时,不必显式定义一个封装仅仅有一个參数的方法的托付。下面演示样例简化了此代码,它所用的方法是实例化
Func<T, TResult>托付,而不是显式定义一个新托付并将命名方法分配给该托付。
使用Func<>托付,我们这样写
using System; public classLambdaExpression
{
public static void Main()
{
Func<string, string> convert = s=> s.ToUpper();//该方法将小写字母转为大写
string name = "Dakota";
Console.WriteLine(convert(name));
}
}
Func托付是system下的全局函数,不用我们自定,系统自己定义的,供我们使用,带有多个重载.
这里我们除了使用Func托付外,还是用了Labdab表达式.这里我再谈谈这个表达式.
Lambda表达式的基础类型是泛型 Func托付之中的一个。 这样能以參数形式传递
lambda表达式,而不用显式将其分配给托付。
尤其是,由于 System.Linq命名空间中很多类型方法具有Func<T,
TResult>參数,因此能够给这些方法传递 lambda表达式。而不用显式实例化
Func<T, TResult>托付。
以下一行代码将生成一个序列,当中包括 numbers 数组中在
9左側的全部元素。由于它是序列中第一个不满足条件的数字:
int[] n= { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
实例2
var firstSmallNumbers =numbers.TakeWhile((n, index) => n >= index);
此演示样例展示了怎样通过将输入參数括在括号里来指定多个输入參数。该方法将返回数字数组中的全部元素,直至遇到一个值小于其位置的数字为止。不要将
lambda运算符 (=>)与大于等于运算符 (>=)混淆。
三种托付写法对照
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace func
{
//托付声明 -- 定义一个签名:
delegate double MathAction(double num);
public class Program
{
// 符合托付声明的常规方法
static double Double(double input)
{
return input * 2;
} static void Main(string[] args)
{
// 使用一个命名方法实例化托付类型
/*
* 写法一,须要写出专门托付的函数,还须要自己定义托付
**/
MathAction ma = Double;//注意这里千万不可有Double(),否则就成了一个返回类型。是报错的,这里是制定函数的地址,给定的是函数的地址 //调用托付
double result1 = ma(4.5); //使用系统自己定义托付实例化托付类型
/*
* 写法二。须要写出专门托付的函数。不须要自己定义托付。使用系统托付
**/
Func<double,double> func = Double; //调用托付
double result2 = func(4.5); //系统托付使用lamdba进行传递參数
/*
* 写法三。不须要写出专门托付的函数。还须要自己定义托付
**/
Func<double, double> result = s=> s * 2;//写法还能够换成lamdba语句块,适应多个參数的写法 double result3=result(4.5); Func<double,double> result4 = s =>
{
return s * 2;
}; Console.WriteLine(result1);
Console.WriteLine(result3);
Console.WriteLine(result2);
Console.WriteLine(result4(4.5));
}
} }
效果图
相同的输出效果,可是编写代码的质量确有不同。当然了也是要对自己的问题进行负责的。lamdba的使用简化的代码。可是假设自己不是对这个非常熟悉,非常easy造成出现故障,如从着手错误的源泉。匿名函数的写法解决的这个问题。可是匿名函数却没有Lamdba简便。这就是折中方法吧。看自己更喜欢哪种了。
小结:
从Func的托付中。我们能够看出,它简化了我们自定义托付带来的繁琐。同一时候它更好的结合了Lamdba的使用。降低了自定义函数的作用。同一时候也是有缺点的,就是错误的出现不easy发现是那里。
Action托付的使用与Func雷同。这里就不在说了。希望自己的总结能够对大家有所帮助。
C# Func<>托付的更多相关文章
- 6.5.2 C# 中的函数组合
6.5.2 C# 中的函数组合 C# 中的函数组合是可能的.但使用非常有限,这是部分是由于在 C# 中散应用不能非常easy使用.但更重要的是,由于大多数操作是用成员来写的.而不是函数.但我们至少能够 ...
- c#Lamdba表达式与托付
介绍: "Lambda表达式"(lambda expression)是一个匿名函数,在C#3.0中引入了lambda表达式,它是对匿名函数的一种简化,能够包括表达式和语句,而且可用 ...
- 浅析C#中的托付
托付是寻址方法的.NET版本号.在C++中.函数指针仅仅只是是一个指向内存位置的指针,它不是类型安全的.而.NET托付全然不同,托付是安全类型的类,它定义了返回类型和參数的类型. 当把方法传递给其它方 ...
- C#托付之愚见
C#托付起源 近期參加实习和奔走于各大招聘会,被问及非常多技术方面的问题.C#问的较多的就是托付和linq. linq之前已经写过一篇文章,能够參见 http://blog.csdn.net/yzys ...
- C#基础知识六之委托(delegate、Action、Func、predicate)
1. 什么是委托 官方解释 委托是定义方法签名的类型,当实例化委托时,您可以将其实例化与任何具有兼容签名的方法想关联,可以通过委托实例调用方法. 个人理解 委托通俗一点说就是把一件事情交给别人来帮助完 ...
- C#委托的介绍(delegate、Action、Func、predicate)
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 (1). delegate delegate我们常用到的一种声明 Deleg ...
- winform总结2> Action<> ,Action,func<>,委托相关的理解
1,他们是什么: Action 封装一个方法,该方法不具有参数并且不返回值. Action<> 封装一个方法,该方法具有最多16个参数并且不返回值. func<> 封装一个具有 ...
- Func
Func<List<int>, string> getStr = (list) => { var returnStr = ""; if (list.A ...
- 浅谈C#中常见的委托<Func,Action,Predicate>(转)
一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的. 关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微,尤其是张子阳的那一篇.我就不 ...
随机推荐
- Javascript Utils.js
\ var Utils ={//字符串格式化StringFormat: function () {if (arguments.length == 0)return null;var str = arg ...
- Mysql 的存储过程和存储函数
优点: v 提高安全性 v 简化mysql查询 v 减轻带宽负担 缺点: v 增加服务器负担 v 对我们开发者来说,难度大一点 PHP中的函数 Function funname(参数){ //函数体 ...
- Ecshop ajax 局部刷新购物车功能
1.比如我们category.dwt 里有 <a href='flow.php'><SPAN id='cart_count_all'>{insert name='cart_in ...
- KVO KVC
@interface FoodData : NSObject { NSString * foodName; float foodPrice; } @end ////////////////////// ...
- Mobile testing基础之签名
1. 什么是数字签名? 数字签名就是为你的程序打上一种标记,来作为你自己的标识,当别人看到签名的时候会知道它是与你相关的 2. 为什么要数字签名? 最简单直接的回答: 系统要求的. Android系统 ...
- Github上如何取消fork别人的repository
在Github上如果看到有很不错的项目和作品,一般我们可以进行三种操作:那就是watch, star和fork. Watch也就是关注该repo的动态,star则类似于Facebook和Twitter ...
- mysql怎么让一个存储过程定时执行
比如说每天的12:30执行 查看event是否开启: show variables like '%sche%'; 将事件计划开启: set global event_scheduler=1; 关闭事件 ...
- Windows10输入法的切换
Alt+Shift 中⇒あ,あ⇒中 Shift 中⇒英,英⇒中 Alt+Caps Lock あ⇒カ,A⇒あ⇒カ Ctrl+Caps Loc ...
- 《Java数据结构与算法》笔记-CH4-2用栈实现字符串反转
import java.io.BufferedReader; import java.io.InputStreamReader; //用栈来实现一个字符串逆序算法 /** * 数据结构:栈 */ cl ...
- NodeJS学习:爬虫小探补完计划
说明:本文在个人博客地址为edwardesire.com,欢迎前来品尝. 书接上回,我们需要修改程序以达到连续抓取40个页面的内容.也就是说我们需要输出每篇文章的标题.链接.第一条评论.评论用户和论坛 ...