Deep in C# Syntactic Sugar
Zhiming Jiang
MSN GMD CSL & Integration
TOPIC
• C#的发展过程
• 面向对象如何被支持
• Var关键词
• 认识泛型
• Yiled的使用
• Lambda & LINQ
计算机不懂对象
编程语言中是怎么实现面向对象的
面向过程
• 冯诺依曼体系
• 顺序化执行
• 数据和结构紧紧耦合
• 难以进行扩展
• 仍能做出好的软件
面向对象
• 计算机面向人类思维的一次转变
• 面对更复杂的事物时提供一种解
决方案
• 抽象机制和现实接近
• 易于扩展
语言层面实现的本质
• 对象字段编译完后和过程语言中的struct一样
• 编译器将所有的对象方法转为普通方法
• Private Public 在编译后都不再存在
• 方法参数列表中加入指向自身的一个参数(this)
– 如Python中self(不是类本身,而是实例本身)
* 以上以C和C++为参考进行对比,C#则引入Metadata机制
C# 执行流程
C#
• dgasfgas
IL• CLR
机器码• JIT
可爱的VAR
由编译器在编译时推断出类型
VAR的作用
• 它有利于更好地为本地变量命名。
• 它有利于设计更好的API。
• 它促使对变量进行初始化。
• 它消除了代码的混乱。
• 它不需要using指示符。
• 过度使用var会使得源代码晦涩难懂。
• 在使用变量之前,通常需要将变量初始化为null,而var关键字对此却不支持
*本段摘自: http://www.infoq.com/news/2008/05/CSharp-var
Source
static void Main(string[] args)
{
var strab = “Hello”;
string strdc = “World”;
}
I L
.entrypoint
// Code size 14 (0xe)
.maxstack 1
.locals init ([0] string strab,
[1] string strdc)
IL_0000: nop
IL_0001: ldstr "Hello"
IL_0006: stloc.0
IL_0007: ldstr "World"
IL_000c: stloc.1
IL_000d: ret
• 由编译器在编译时推断出类型
• ldstr: load String 将字符串入栈
• .Net Reflector Tool
认识泛型
泛型是怎么被实现的
意义:
复用
装箱拆箱所带来的性能问题
约束
泛型本质
• 依然是占位符
• JIT会为值类型创建各自的本地代码实现
• 引用类型实际都共享一个方法的代码(避免方法爆炸)
* 1. 示例代码摘至: CLR内部有太多太多IL看不到的东西,包括您平时必须了解的那些
* 2. 思考: 为什么将泛型实现交给JIT,而非由CLR直接处理
private static void
GenericMethod<T>(){
Console.WriteLine(typeof(T));
}
static void Main(string[] args){
GenericMethod<string>();
GenericMethod<int>();
GenericMethod<object>();
GenericMethod<DateTime>();
GenericMethod<Program>();
GenericMethod<double>();
Console.ReadLine();
}
00a70071 mov ebp,esp
00a70073 mov ecx,3A30C4h (MD: ....GenericMethod[[System.String
00a70078 call dword ptr ds:[3A3098h]
(....GenericMethod[[System.__Canon,
00a7007e call dword ptr ds:[3A3108h] (....GenericMethod[[System.Int32
00a70084 mov ecx,3A3134h (MD: ....GenericMethod[[System.Object
00a70089 call dword ptr ds:[3A3098h]
(....GenericMethod[[System.__Canon
00a7008f call dword ptr ds:[3A3178h]
(....GenericMethod[[System.DateTime
00a70095 mov ecx,3A31A4h
(MD: ....GenericMethod[[TestConsole.Program
00a7009a call dword ptr ds:[3A3098h]
(....GenericMethod[[System.__Canon
00a700a0 call dword ptr ds:[3A31E8h]
(....GenericMethod[[System.Double
认识YIELD
• 简化迭代
• 延迟计算
Yiled本质
• CLR后台生成一个标准的迭代器全代码
• 调用时执行,延迟技术,对查询条件进行优化
• [Code Demo]
LAMBDA & LINQ
Lambda
//1.0
delegate int Dele(string s);
static int Find(string s){
return s.IndexOf("abc");
}
Dele t = new Dele(Find);
//2.0 匿名方法
fruits.Find(delegate(string s) { return s.IndexOf("abc"; });
//3.0 Lambda
fruits.Find(s => s. s.IndexOf("abc"));
* 课后练习:自己动手分析Lambda背后的IL代码
C#语言的方向 • 功能化
• 语义化
• 多核并行
• 动态
IT IS OVER,THANKS

Deep in c# syntactic sugar

Editor's Notes

  • #17 在1.0时代我们要声明一个方法,挂到委托对象上。 整个Lambda表达式是一个值,委托类型 更接近人的思维,