DEV 331 深度探索 Microsoft Visual C# 2.0 2018年11月21日6时44分 DEV 331 深度探索 Microsoft Visual C# 2.0 付仲恺 微软特邀开发专家 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
C# 2.0增强 范型(Generics) 匿名方法(Anonymous methods) 可为空类型(Nullable types) 2018年11月21日6时44分 C# 2.0增强 范型(Generics) 匿名方法(Anonymous methods) 可为空类型(Nullable types) 迭代器(Iterators) 局部类型(Partial types) 等等 100%向后兼容 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) public class List { private object[] elements; 2018年11月21日6时44分 范型(Generics) public class List { private object[] elements; private int count; public void Add(object element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public object this[int index] { get { return elements[index]; } set { elements[index] = value; } public int Count { get { return count; } public class List<T> { private T[] elements; private int count; public void Add(T element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public T this[int index] { get { return elements[index]; } set { elements[index] = value; } public int Count { get { return count; } List<int> intList = new List<int>(); intList.Add(1); // No boxing intList.Add(2); // No boxing intList.Add("Three"); // Compile-time error int i = intList[0]; // No cast required List intList = new List(); intList.Add(1); intList.Add(2); intList.Add("Three"); int i = (int)intList[0]; List intList = new List(); intList.Add(1); // Argument is boxed intList.Add(2); // Argument is boxed intList.Add("Three"); // Should be an error int i = (int)intList[0]; // Cast required © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 为什么需要范型? C#如何实现范型? 类型检查,不进行拆箱和类型强制转换 增加了代码重用机会(类型集合) 2018年11月21日6时44分 范型(Generics) 为什么需要范型? 类型检查,不进行拆箱和类型强制转换 增加了代码重用机会(类型集合) C#如何实现范型? 在运行时实例化,而不是编译时 类型检查在声明时,而不是实例化时进行 同时支持引用和值类型 完整的运行时类型信息 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 类型参数能够被应用于: 类,结构体,接口,委托类型 2018年11月21日6时44分 范型(Generics) 类型参数能够被应用于: 类,结构体,接口,委托类型 class Dictionary<K,V> {...} struct HashBucket<K,V> {...} interface IComparer<T> {...} delegate R Function<A,R>(A arg); Dictionary<string,Customer> customerLookupTable; Dictionary<string,List<Order>> orderLookupTable; Dictionary<string,int> wordCount; © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 类型参数能够被应用于: 类,结构体,接口,委托类型 方法 类型推断! class Utils { 2018年11月21日6时44分 范型(Generics) 类型参数能够被应用于: 类,结构体,接口,委托类型 方法 class Utils { public static T[] CreateArray<T>(T value, int size) { T[] result = new T[size]; for (int i = 0; i < size; i++) result[i] = value; return result; } string[] names = Utils.CreateArray<string>("", 10); int[] numbers = Utils.CreateArray<int>(-1, 100); string[] names = Utils.CreateArray("", 10); int[] numbers = Utils.CreateArray(-1, 100); 类型推断! © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 类型参数能够被应用于: 类型参数能够具有约束 类,结构体,接口,委托类型 方法 2018年11月21日6时44分 范型(Generics) 类型参数能够被应用于: 类,结构体,接口,委托类型 方法 类型参数能够具有约束 class Dictionary<K,V>: IDictionary<K,V> where K: IComparable<K> where V: IKeyProvider<K>, IPersistable, new() { public void Add(K key, V value) { ... } class Dictionary<K,V> where K: IComparable { public void Add(K key, V value) { ... if (key.CompareTo(x) == 0) {...} } class Dictionary<K,V> { public void Add(K key, V value) { ... if (((IComparable)key).CompareTo(x) == 0) {...} } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 只允许有一个基本约束 可以有多个次要约束 可以有一个构造约束 实际类,或者结构体 接口或者类型参数 new() 2018年11月21日6时44分 范型(Generics) 只允许有一个基本约束 实际类,或者结构体 可以有多个次要约束 接口或者类型参数 可以有一个构造约束 new() class Link<T> where T: class {...} class Nullable<T> where T: struct {...} class Relation<T,U> where T: class where U: T {...} © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) default(T) 类型转换 Null检查 void Foo<T>() { 2018年11月21日6时44分 范型(Generics) void Foo<T>() { T x = null; // Error T y = default(T); // Ok } default(T) 类型转换 Null检查 void Foo<T>(T x) { int i = (int)x; // Error int j = (int)(object)x; // Ok } void Foo<T>(T x) { if ((object)x == null) {...} } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
范型(Generics) 集合类 集合接口 集合基本类 工具类 反射 List<T> Dictionary<K,V> 2018年11月21日6时44分 范型(Generics) List<T> Dictionary<K,V> SortedDictionary<K,V> Stack<T> Queue<T> 集合类 集合接口 集合基本类 工具类 反射 IList<T> IDictionary<K,V> ICollection<T> IEnumerable<T> IEnumerator<T> IComparable<T> IComparer<T> Collection<T> KeyedCollection<T> ReadOnlyCollection<T> Nullable<T> EventHandler<T> Comparer<T> © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
2018年11月21日6时44分 范型(Generics)性能 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
匿名方法(Anonymous Methods) 2018年11月21日6时44分 匿名方法(Anonymous Methods) delegate bool Predicate<T>(T item); public class List<T> { public List<T> FindAll(Predicate<T> filter) { List<T> result = new List<T>(); foreach (T item in this) { if (filter(item)) result.Add(item); } return result; public class Bank { List<Account> accounts; List<Account> GetOverdrawnAccounts() { return accounts.FindAll( new Predicate<Account>(IsOverdrawn) ); } static bool IsOwerdrawn(Account a) { return a.Balance < 0; public class Bank { List<Account> accounts; List<Account> GetOverdrawnAccounts() { return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } ); } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
匿名方法(Anonymous Methods) 2018年11月21日6时44分 匿名方法(Anonymous Methods) 代码块替代委托方法 自动推断委托类型 代码块可以忽略参数列表 button.Click += delegate { MessageBox.Show("Hello"); }; button.Click += delegate(object sender, EventArgs e) { MessageBox.Show(((Button)sender).Text); }; © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
匿名方法(Anonymous Methods) 2018年11月21日6时44分 匿名方法(Anonymous Methods) 支持Closures public class Bank { List<Account> accounts; List<Account> GetOverdrawnAccounts() { return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } ); } List<Account> GetLargeAccounts(double minBal) { delegate(Account a) { return a.Balance >= minBal; } public class Bank { List<Account> accounts; List<Account> GetOverdrawnAccounts() { return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } ); } public class Bank { List<Account> GetLargeAccounts(double minBal) { Helper helper = new Helper(); helper.minBal = minBal; return accounts.FindAll(helper.Matches); } internal class Helper internal double minBal; internal bool Matches(Account a) { return a.Balance >= minBal; } } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
匿名方法(Anonymous Methods) 2018年11月21日6时44分 匿名方法(Anonymous Methods) 方法组转换 在可能的情况下,推断出委托类型 using System; using System.Threading; class Program { static void Work() {...} static void Main() { Thread t = new Thread(new ThreadStart(Work)); t.Start(); } using System; using System.Threading; class Program { static void Work() {...} static void Main() { Thread t = new Thread(Work); t.Start(); } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
匿名方法 (Anonymous Methods) 2018年11月21日6时44分 匿名方法 (Anonymous Methods) © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
可为空类型(Nullable Types) 2018年11月21日6时44分 可为空类型(Nullable Types) System.Nullable<T> 为所有值类型提供可为空的能力 具有类型T和布尔值的结构体 int 123 public struct Nullable<T> where T: struct { private T value; private bool hasValue; public T Value { get { … } } public bool HasValue { get { … } } } Nullable<int> 123 ??? true false Non-null Null © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
Nullable Types T? 语法 null 赋值 不同类型转换 Lifted操作符 Null结合运算符 int? x = 123; 2018年11月21日6时44分 Nullable Types T? 语法 null 赋值 不同类型转换 Lifted操作符 Null结合运算符 int? x = 123; double? y = 1.0; int? x = null; double? y = null; int i = 123; int? x = i; // T T? implicit int j = (int)x; // T? T explicit int? x = GetNullableInt(); int? y = GetNullableInt(); int? z = x + y; int? x = GetNullableInt(); int i = x ?? 0; © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
迭代器(Iterators) foreach依赖于“枚举模式” foreach使得枚举变得更加方便 GetEnumerator() 方法 2018年11月21日6时44分 迭代器(Iterators) foreach依赖于“枚举模式” GetEnumerator() 方法 foreach使得枚举变得更加方便 但是枚举器的实现难度加大了! foreach (object obj in list) { DoSomething(obj); } Enumerator e = list.GetEnumerator(); while (e.MoveNext()) { object obj = e.Current; DoSomething(obj); } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
迭代器(Iterators) public class ListEnumerator : IEnumerator { List list; 2018年11月21日6时44分 迭代器(Iterators) public class ListEnumerator : IEnumerator { List list; int index; internal ListEnumerator(List list) { this.list = list; index = -1; } public bool MoveNext() { int i = index + 1; if (i >= list.count) return false; index = i; return true; public object Current { get { return list.elements[index]; } public class List { internal object[] elements; internal int count; public IEnumerator GetEnumerator() { return new ListEnumerator(this); } public class List { internal object[] elements; internal int count; public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { yield return elements[i]; } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
迭代器(Iterators) 方法递增计算并且返回一系列数值 yield return和yield break 2018年11月21日6时44分 迭代器(Iterators) public IEnumerator GetEnumerator() { return new __Enumerator(this); } private class __Enumerator : IEnumerator { object current; int state; public bool MoveNext() { switch (state) { case 0: current = "Hello"; state = 1; return true; case 1: current = "World"; state = 2; return true; default: return false; public object Current { get { return current; } 方法递增计算并且返回一系列数值 yield return和yield break 必须返回IEnumerator或者IEnumerable public class Test { public IEnumerator GetEnumerator() { yield return "Hello"; yield return "World"; } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
迭代器(Iterators) public class List<T> { 2018年11月21日6时44分 迭代器(Iterators) public class List<T> { public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++) yield return elements[i]; } public IEnumerable<T> Descending() { for (int i = count - 1; i >= 0; i--) public IEnumerable<T> Subrange(int index, int n) { for (int i = 0; i < n; i++) yield return elements[index + i]; List<Item> items = GetItemList(); foreach (Item x in items) {...} foreach (Item x in items.Descending()) {...} foreach (Item x in Items.Subrange(10, 20)) {...} © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
2018年11月21日6时44分 迭代器(Iterators) © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
局部类型(Partial Types) public partial class Customer { private int id; 2018年11月21日6时44分 局部类型(Partial Types) public partial class Customer { private int id; private string name; private string address; private List<Orders> orders; } public class Customer { private int id; private string name; private string address; private List<Orders> orders; public void SubmitOrder(Order order) { orders.Add(order); } public bool HasOutstandingOrders() { return orders.Count > 0; public partial class Customer { public void SubmitOrder(Order order) { orders.Add(order); } public bool HasOutstandingOrders() { return orders.Count > 0; © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
静态类(Static Classes) 只有静态成员 不能被用于变量,参数,域,属性等类型 2018年11月21日6时44分 静态类(Static Classes) 只有静态成员 不能被用于变量,参数,域,属性等类型 例如:System.Console,System.Environment public static class Math { public static double Sin(double x) {...} public static double Cos(double x) {...} ... } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
属性访问器(Property Accessors) 2018年11月21日6时44分 属性访问器(Property Accessors) 不同的访问器访问权限 访问器能够被严格限制 一般来说,set{…}的权限更加严格 public class Customer { private string id; public string CustomerId { get { return id; } internal set { id = value; } } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
外部别名(External Aliases) 2018年11月21日6时44分 外部别名(External Aliases) 在不同的程序集中使用相同的命名类型 namespace Stuff { public class Utils public static void F() {...} } foo.dll extern alias Foo; extern alias Bar; class Program { static void Main() { Foo.Stuff.Utils.F(); Bar.Stuff.Utils.F(); } namespace Stuff { public class Utils public static void F() {...} } bar.dll C:\>csc /r:Foo=foo.dll /r:Bar=bar.dll test.cs © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
命名空间别名修饰符 (Namespace Alias Qualifiers) 2018年11月21日6时44分 命名空间别名修饰符 (Namespace Alias Qualifiers) 版本上更加有弹性的代码 A::B仅将A作为别名 global::X作为全局命名空间 using IO = System.IO; class Program { static void Main() { IO::Stream s = new IO::File.OpenRead("foo.txt"); global::System.Console.WriteLine("Hello"); } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
内联警告控制 (Inline Warning Control) 2018年11月21日6时44分 内联警告控制 (Inline Warning Control) #pragma warning using System; class Program { [Obsolete] static void Foo() {} static void Main() { #pragma warning disable 612 Foo(); #pragma warning restore 612 } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
固定大小缓冲区 (Fixed Size Buffers) 2018年11月21日6时44分 固定大小缓冲区 (Fixed Size Buffers) 在非安全代码中的C语言风格数组 public struct OFSTRUCT { public byte cBytes; public byte fFixedDisk; public short nErrCode; private int Reserved; public fixed char szPathName[128]; } © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.