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