在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能。基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用。同时,它减少了泛型类及泛型方法中的转型,确保了类型安全。委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是对方法的引用。事件本身也是委托,它是委托组,C#中提供了关键字event来对事件进行特别区分。一旦我们开始编写稍微复杂的C#代码,就肯定离不开泛型、委托和事件。本章将针对这三个方面进行说明。 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要学习记录以下内容: 建议35、使用default为泛型类型指定初始值 建议36、使用FCL中的委托声明 建议37、使用lambda表达式代替方法和匿名方法 建议35、使用default为泛型类型指定初始值 有些算法,比如泛型集合List<T>的Find算法,所查找的对象有可能会是值类型,也有可能是引用类型。在这种算法内部,我们常常会为这些值类型变量或引用类型变量指定默认值。于是,问题来了:值类型变来那个的默认初始值是0值,而引用类型变量的默认初始值是null值,显然,这会导致下面编译出错: C#编译器会阻止这样的代码通过编译。要让编译器接收为一个泛型类型参数指定一个初始值,最妥当的办法就是使用default关键字。所以,在上面的代码应该改为: public T Func<T>() { T t = default(T); return t; } 这样如果它在运行时碰到的T是一个整型,那么运行时会为其赋值0;如果T在运行时是一个Person这样的引用类型,则会为其赋null值。 建议36、使用FCL中的委托声明 要注意FCL中存在三类这样的委托声明,他们分别是:Action、Func、Predicate。尤其是在他们的泛型版本出来以后,已经能够满足我们在实际编码过程中的大部分需要。 这里是之前一篇关于Action、Func、Predicate的有关介绍http://www.cnblogs.com/aehyok/p/3382291.html 除了Action、Func、Predicate外,FCL中还有用于标识特殊含义的委托声明。如用于表示注册事件方法的委托声明: public delegate void EventHandler(object sender,EventArgs e); public delegate void EnentHandler<TEventArgs>(object sender,TEventArgs e); 表示线程的委托声明: public delegate void ThreadStart(); public delegate void ParameterizedThreadStart(object obj); 表示异步回调的委托声明: public delegate void AsyncCallback(IAsyncResult ar); 在FCL中没一类委托声明都代表一类特殊的用途,虽然可以使用自己的委托声明来代替,但是这样做不仅没有必要,而且会让代码失去简洁性和标准型。在我们实现自己的委托声明前,应该首先查看MSDN,确信有必要之后才这样做。 建议37、使用lambda表达式代替方法和匿名方法 首先我们使用Action和Func来做一个简单的小例子,控制台应用程序代码如下所示: 第一个版本 class Program { static int Add(int i, int j) { return i + j; } static void Print(string message) { Console.WriteLine(message); } static void Main(string[] args) { Func<int, int, int> add = Add; Action<string> print = Print; print(add(4, 5).ToString()); Console.ReadLine(); } } 实际上要完成上面的功能,还有多种编码方式,先来看一种最中规中矩的方式,同时也是最繁琐的写法: 第二个版本 class Program { static int Add(int i, int j) { return i + j; } static void Print(string message) { Console.WriteLine(message); } static void Main(string[] args) { Func<int, int, int> add = new Func<int,int,int>(Add); Action<string> print =new Action<string>(Print); print(add(4, 5).ToString()); Console.ReadLine(); } } 其实也就是将第一个版本稍作调整。从上面的写法中也可以看出:Add方法和Print方法实际上都只有一条语句,因此,使用匿名方法也许是一种更好的选择: 第三个版本 static void Main(string[] args) { Func<int, int, int> add = new Func<int,int,int>(delegate(int i,int j) { return i+j; }); Action<string> print =new Action<string>(delegate(string message) { Console.WriteLine(message); }); print(add(4, 5).ToString()); Console.ReadLine(); } 使用匿名方法以后,我们不需要在Main方法外部声明两个方法了,可以直接在Main这个工作方法中完成所有的代码编写,而且不会影响代码清晰性。实际上,所有代码行数不超过3行的方法(条件是它不倍重用),我们都建议采用这种方式来编写。上面的版本继续改进: 第四个版本 static void Main(string[] args) { Func<int, int, int> add = delegate(int i,int j) { return i+j; }; Action<string> print =delegate(string message) { Console.WriteLine(message); }; print(add(4, 5).ToString()); Console.ReadLine(); } 以上代码看上去更简化了,不过,最终极的改进是使用lambda表达式: 第五个版本 static void Main(string[] args) { Func<int, int, int> add = (x, y) => x + y; Action<string> print = (message) => Console.WriteLine(message); print(add(4, 5).ToString()); Console.ReadLine(); } Lambda表达式操作符”=>“的左侧是方法的参数,右侧是方法体,其本质是匿名方法。实际上,经过编译后Lambda表达式就是一个匿名方法。我们应该在实际的编码工作中熟练运用它,避免写出繁琐且不美观的代码。
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论