《C#本质论》读书笔记(12)委托和Lambda表达式
12.1.委托概述
12.1.2 委托的数据类型
class DelegateSample
{
static void Main(string[] args)
{
//int[] arr = { 10, 20, 30, 40, 50 };
int[] arr = { 50, 40, 30, 20, 10 };
ConsoleArr(arr);
ComparisonHandler wx = new ComparisonHandler(DelegateSample.IsTrue);
BubbleSort(arr, wx);
- //C#2.0之前是这么写的
- //BubbleSort(arr, new ComparisonHandler(IsTrue));
ConsoleArr(arr);
Console.Read();
}
public delegate bool ComparisonHandler(int a, int b);
public static bool IsTrue(int a, int b)
{
return a > b;
}
public static void BubbleSort(int[] items, ComparisonHandler comparisonMethod)
{
int i;
int j;
int temp;
if (items == null)
{
return;
}
if (comparisonMethod == null)
{
throw new ArgumentNullException("comparisonMethod");
}
for (i = items.Length - 1; i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (comparisonMethod(items[j - 1], items[j]))
{
temp = items[j - 1];
items[j - 1] = items[j];
items[j] = temp;
}
}
}
}
public static void ConsoleArr(int[] arr)
{
foreach (var item in arr)
{
Console.Write(item+",");
}
Console.WriteLine();
}
}
public static bool AlphabeticalIsTrue(int a,int b)
{
int comparison;
comparison = (a.ToString().CompareTo(b.ToString()));
return comparison > 0;
}
//C# 2.0以后直接传递方法
BubbleSort(arr, AlphabeticalIsTrue);
12.1.3 委托内部机制
// 摘要:
// 初始化一个委托,该委托对指定的类实例调用指定的实例方法。
//
// 参数:
// target:
// 类实例,委托对其调用 method。
//
// method:
// 委托表示的实例方法的名称。
//
// 异常:
// System.ArgumentNullException:
// target 为 null。 - 或 - method 为 null。
//
// System.ArgumentException:
// 绑定到目标方法时出错。
[SecuritySafeCritical]
protected Delegate(object target, string method);
//
// 摘要:
// 初始化一个委托,该委托从指定的类调用指定的静态方法。
//
// 参数:
// target:
// System.Type,它表示定义 method 的类。
//
// method:
// 委托表示的静态方法的名称。
//
// 异常:
// System.ArgumentNullException:
// target 为 null。 - 或 - method 为 null。
//
// System.ArgumentException:
// target 不是 RuntimeType。 请参见 反射中的运行时类型。 - 或 - target 表示开放式泛型类型。
[SecuritySafeCritical]
protected Delegate(Type target, string method);
12.2.匿名方法
class Program
{
public delegate bool ComparisonHandler(int a, int b);
static void Main(string[] args)
{
int i;
int[] items = new int[5];
ComparisonHandler comparionMethod;
for (i = 0; i < items.Length; i++)
{
Console.WriteLine("Enter an integer:");
items[i] = int.Parse(Console.ReadLine());
}
comparionMethod = delegate(int first, int second)
{
return first < second;
};
BubbleSort(items, comparionMethod);
for ( i = 0; i < items.Length; i++)
{
Console.WriteLine(items[i]);
}
Console.Read();
}
public static void BubbleSort(int[] items, ComparisonHandler comparisonMethod)
{
int i;
int j;
int temp;
if (items == null)
{
return;
}
if (comparisonMethod == null)
{
throw new ArgumentNullException("comparisonMethod");
}
for (i = items.Length - 1; i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (comparisonMethod(items[j - 1], items[j]))
{
temp = items[j - 1];
items[j - 1] = items[j];
items[j] = temp;
}
}
}
}
}

12.3.系统定义的委托:Func 和 Action 声明

公共语言运行时提供 Invoke 每种委托类型,具有相同的签名与委托的方法。 您不需要显式调用此方法,从 C#、 Visual Basic 或 Visual c + +,因为编译器会自动调用。 Invoke 方法就很有用 反射 如果想要查找的委托类型签名。
https://msdn.microsoft.com/zh-cn/library/system.delegate.aspx
12.4.语句Lambda
1.无参数的语句
static void Main(string[] args)
{
//...
Func<string> getUserInput =
() =>
{
string input;
do
{
input = Console.ReadLine();
}
while (input.Trim().Length == 0);
return input;
};
//...
}
2.只有一个参数的语句
IEnumerable<Process> processes = Process.GetProcesses()
.Where(process => { return process.WorkingSet64 > 100000000; });
12.5.表达式Lambda
BubbleSort(items, (first, second) => first > second);
BubbleSort(items, (first, second) =>
{
return first > second;
}
);
12.6.表达式树
1.Lambda表达式作为数据使用
class Program
{
static void Main(string[] args)
{
Person[] persons = new Person[3];
IEnumerable<Person> obj = persons.Where(person => person.Name.ToUpper() == "INIGO MONTOYA");
}
}
public class Person
{
public string Name { get; set; }
}
一个技术是将几百万数据传输到客户端,为每一行创建一个Person对象,根据Lambda创建一个委托,再针对每个Person执行这个委托。概念上和数组的情况一致,但代价过于昂贵。
.第二个技术要好很多,将Lambda的含义(过滤掉姓名不是INIGO MONTOYA的每一行)发给服务器。服务器将符合条件的少数几行传输到客户端;而不是先创建几百万个Person对象,再丢弃。但是没在那将Lambda的含义发送给服务器?
这正式语言中添加表达式树这一概念的动机。
对Person的Name属性的调用;
对string的ToUpper()方法调用;
一个常量值“INIGO MONTOYA”;
一个相等性操作符==。
2.表达式树作为对象图使用
3.委托和表达式树的比较
IEnumerable<Person> obj = persons.Where(person => person.Name.ToUpper() == "INIGO MONTOYA");
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate)
4.解析表达式
(x,y)=>x>y
Func<int,int,bool>
| 名称 | 说明 | |
|---|---|---|
![]() ![]() |
Body | 获取 lambda 表达式的主体。 (继承自 LambdaExpression。) |
![]() |
CanReduce | 指示可将节点简化为更简单的节点。 如果返回 true,则可以调用 Reduce() 以生成简化形式。 (继承自Expression。) |
![]() |
Name | 获取 lambda 表达式的名称。 (继承自 LambdaExpression。) |
![]() ![]() |
NodeType | Expression." xml:space="preserve">返回此 Expression 的节点类型。 (继承自 LambdaExpression。) 在 Silverlight for Windows Phone Windows Phone OS 7.1 中,此成员是从 Expression.NodeType 中继承的。 在 XNA Framework Windows Phone OS 7.0 中,此成员是从 Expression.NodeType 中继承的。 |
![]() ![]() |
Parameters | 获取 lambda 表达式的参数。 (继承自 LambdaExpression。) |
![]() |
ReturnType | 获取 lambda 表达式的返回类型。 (继承自 LambdaExpression。) |
![]() |
TailCall | 获取一个值,该值指示是否将通过尾调用优化来编译 lambda 表达式。 (继承自 LambdaExpression。) |
![]() ![]() |
Type | Expression represents." xml:space="preserve">获取此 Expression 所表示的表达式的静态类型。 (继承自 LambdaExpression。) 在 Silverlight for Windows Phone Windows Phone OS 7.1 中,此成员是从 Expression.Type 中继承的。 在 XNA Framework Windows Phone OS 7.0 中,此成员是从 Expression.Type 中继承的。 |
Expression<Func<int, int, bool>> expression;
expression = (x, y) => x > y;
Console.WriteLine("------{0}------",expression);
PrintNode(expression.Body, 0);//expression.Body: (x > y) [lambda 表达式的主体]
Console.WriteLine();
Console.WriteLine();
expression = (x, y) => x * y > x + y;
Console.WriteLine("------{0}------",expression);
PrintNode(expression.Body, 0); //expression.Body: (x * y) > (x + y)
/*
* expression.Body: (x * y) > (x + y) [lambda 表达式的主体]
* BinaryExpression是否具有二进制运算符:true
* expression.Left:(x * y)
* BinaryExpression是否具有二进制运算符:true
* expression.Left:x expression.NodeType:Parameter
* BinaryExpression是否具有二进制运算符:false
* expression.Left:* expression.NodeType:Multiply
* .....
*/
Console.WriteLine();
Console.WriteLine();
Console.Read();
}
public static void PrintNode(Expression expression, int indent)
{
if (expression is BinaryExpression) //具有二进制运算符的表达式
PrintNode(expression as BinaryExpression, indent);
else
PrintSingle(expression, indent);
}
private static void PrintNode(BinaryExpression expression, int indent)
{
PrintNode(expression.Left, indent + 1);
PrintSingle(expression, indent);
PrintNode(expression.Right, indent + 1);
}
private static void PrintSingle(Expression expression, int indent)
{
Console.WriteLine("{0," + indent * 5 + "}{1}", "", NodeToSting(expression));
}
private static string NodeToSting(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.Multiply:
return "*";
case ExpressionType.Add:
return "+";
case ExpressionType.Divide:
return "/";
case ExpressionType.Subtract:
return "-";
case ExpressionType.GreaterThan:
return ">";
case ExpressionType.LessThan:
return "<";
default:
return expression.ToString() + "(" + expression.NodeType.ToString() + ")";
}
}
注意:Lambda语句不能转换成表达式树,只有表达式Lambda才能转为表达式树。
《C#本质论》读书笔记(12)委托和Lambda表达式的更多相关文章
- 《疯狂Kotlin讲义》读书笔记6——函数和Lambda表达式
函数和Lambda表达式 Kotlin融合了面向过程语言和面向对象语言的特征,相比于Java,它增加了对函数式编程的支持,支持定义函数.调用函数.相比于C语言,Kotlin支持局部函数(Lambda表 ...
- 强化学习读书笔记 - 12 - 资格痕迹(Eligibility Traces)
强化学习读书笔记 - 12 - 资格痕迹(Eligibility Traces) 学习笔记: Reinforcement Learning: An Introduction, Richard S. S ...
- 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...
- C#高级编程(第9版) 第08章 委托、lambda表达式和事件 笔记
本章代码分为以下几个主要的示例文件: 1. 简单委托 2. 冒泡排序 3. lambda表达式 4. 事件示例 5. 弱事件 引用方法 委托是寻址方法的.NET版本.在C++中函数 ...
- 委托、匿名委托、Lambda 表达式、Expression表达式树之刨根问底
本篇不是对标题所述之概念的入门文章,重点在阐述它们的异同点和应用场景.各位看官,这里就不啰嗦了,直接上代码. 首先定义一个泛型委托类型,如下: public delegate T Function&l ...
- 转载 C#匿名函数 委托和Lambda表达式
转载原出处: http://blog.csdn.net/honantic/article/details/46331875 匿名函数 匿名函数(Anonymous Function)是表示“内联”方法 ...
- 十二、C# 委托与Lambda表达式(匿名方法的另一种写法)
委托与Lambda表达式 1.委托概述 2.匿名方法 3.语句Lambda 4.表达式Lambda 5.表达式树 一.委托概述 相当于C++当中的方法指针,在C#中使用delegate 委托来 ...
- 委托与Lambda表达式
~,先不急说委托和Lambda表达式,先看两个例子再说: 1. 通过委托,为一个数字加10,如下代码: class Program { private delegate int JiSuan(int ...
- 系统预定义委托与Lambda表达式
NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式 开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Fun ...
- C#函数式程序设计之函数、委托和Lambda表达式
C#函数式程序设计之函数.委托和Lambda表达式 C#函数式程序设计之函数.委托和Lambda表达式 相信很多人都听说过函数式编程,提到函数式程序设计,脑海里涌现出来更多的是Lisp.Haske ...
随机推荐
- BZOJ1588——[HNOI2002]营业额统计
1.题目大意:一个简单的treap模板题(我才不告诉你题目少一句话呢,看discuss去 2.分析:treap模板题 #include <cstdio> #include <cstd ...
- [BZOJ3572][Hnoi2014]世界树
[BZOJ3572][Hnoi2014]世界树 试题描述 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条 ...
- [KOJ95603]全球奥运
[COJ95603]全球奥运 试题描述 一个环形的图中有N个城市,奥运会重要项目就是传递圣火,每个城市有A[i]个圣火,每个城市可以向它相邻的城市传递圣火(其中1号城市可以传递圣火到N号城市或2号城市 ...
- 如何优雅地使用 Sublime Text
Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相比 于难于上手的Vim,浮肿沉重的Ecli ...
- 我要阻止做java开发的男朋友去创业型公司工作吗?
命这样的标题,我没有瞧不起创业型公司,我只是有点急了,因为男朋友今天晚上就要回复招聘公司了.我先来说说来由吧. 前段时间男朋友离职了,从毕业到现在在公司呆了2年多,因为资金不足导致他做的项目被迫停止了 ...
- mysql 查询某个日期时间段,每天同一时间段的数据
mysql 查询某个日期时间段,每天同一时间段的数据: SELECT * FROM t_a01_eltable WHERE DATE_FORMAT(acqtime,'%Y-%m-%d')>='2 ...
- ZUI前段框架简介
一.说明 基于Bootstrap定制 ZUI继承了Bootstrap 3中的大部分基础内容,但出于与Bootstrap不同的目的,一些组件都进行了定制和修改.这些变化包括: 移除了部分插件的限制,增加 ...
- qmake的使用
[TOC] 本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso 本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso *** 还是先说 ...
- linux 终端报错 Out of memory: Kill process[PID] [process name] score问题分析
从Out of memory来看是内存超出了,后面的 Kill process[PID] [process name] score好像和进程有关了,下面我们就一起来看看linux 终端报错 Out o ...
- js中val()和value的区别
val()是在有jQuery插件的时候才能用,value是在没有jQuery插件的情况下也能用.val()是jQuery根据原生JS里面的value写出来的函数 $(this).val(); 有四个重 ...











