继续《C#入门经典》,Let's go!

方法的重载

重载也是多态的一种体现,其表现形式是方法名相同,但签名不同。所谓签名就是方法名以及参数,换句话说,重载方法就是几个参数不同的同名方法,在调用的时候,编译器根据输入的参数类型选择对应的重载方法。注意的是,返回值不是方法签名的一部分,因此不能定义只有返回值不同的方法。

OverloadSample

 1 int Max(int a, int b) 2 { 3       return a > b ? a : b; 4 } 5  6 double Max(double a, double b) 7 { 8       return a > b ? a : b; 9 }10 11 double Max(ref double a, double b)12 {13       return a > b ? a : b;14 }15 16 //不能定义仅在out和ref上有差别的方法17 //double Max(out double a, double b)18 //{19 //}

委托

C++程序猿可能比较熟悉所谓的“函数指针”,委托就类似于函数指针。我的理解是提供了一种像操作变量一样的操作方法的方式,这么说可能比较抽象,让我们看个例子先:

DelegateSample

 1 class DelegateClass 2 { 3       public delegate int ProcessDelegate(int a, int b); 4 } 5  6 class MethodClass 7 { 8       public int Add(int a, int b) 9       {10             return a + b;11       }12 13       public static int Mutiply(int a, int b)14       {15             return a * b;16       }17 }18 19 class Program20 {21       static void Main(string[] args)22       {23             MethodClass method = new MethodClass();24             DelegateClass.ProcessDelegate addDelegate = new DelegateClass.ProcessDelegate(method.Add);25             DelegateClass.ProcessDelegate mutiplyDelegate = new DelegateClass.ProcessDelegate(MethodClass.Mutiply);26 27             Console.WriteLine(addDelegate(10, 10));28             Console.WriteLine(mutiplyDelegate(10, 10));29             Console.ReadLine();30       }31 }

先看DelegateClass,该类中定义了一个委托,委托定义的语法类似于抽象方法,利用delegate关键字,委托没有方法体。然后我们在MethodClass中定义了两个方法,注意,想方法签名必须和委托定义一致,这样才能使用委托来调用该方法。接着,我们在Main方法中实例化了两个委托,并将MethodClass中的两个方法作为参数分别传入。注意这里的语法,method.Add,MethodClass.Mutiply是不是很类似于属性呢?对委托的实例化是不是也和实例化一个类很类似呢?这就是我之前说的“提供了一种像操作变量一样的操作方法的方式”。实例化之后addDelegate就代表了Add方法,mutiplyDelegate就代表了Mutiply方法,然后就可以像使用普通方法一样来使用委托了。

委托至少在一个地方是非常有用的,当调用者所调用的方法在他编写代码的时候并不能确定的,就需要使用委托,这就是所谓回调,是事件处理的基础。比如由A提供一个委托,B实现一个方法,并传递给A所定义的委托,这样A就可以调用B所实现的方法了。想想点击一个Button的事件处理的方法是谁写的,又是谁在调用你就会明白。我在之后的文章中还会讨论事件处理,到时候会对此再进行研究。

书的第七章分两部分,第一部分主要讲了一些调试的技巧包括断点,条件断点,监视,即时窗口等,十分有用。在这里我就不赘述了,大家最好看图动手,自己尝试一下~第二部分是异常处理,这是一个重要的议题,但感觉和Java十分类似,没什么需要注意的。如果第一次接触的话建议好好看一下,注意异常处理并不是错误处理,而应该把他理解成处理非正常流程的一种很好的方法(一个举烂了的例子,比如在ATM取款的时候发现没钱了,这不是一个正常的流程,但也是十分可能出现的情况,并不是ATM出现错误(故障),只是一种异常的流程而已)。正确的使用异常处理可以极大得增强代码的健壮性。

属性

属性在我看来就是简化了代码,Java中需要给私有变量提供set和get方法,用来安全地访问变量,而在C#中,是利用了属性,看上去不是方法,变得简单了,实际上编译完的MSIL依然是这两个方法,只是我们看不到罢了。

接口

OOP中很重要的概念,不熟悉OOP的好好看看吧。这里主要提一下文中的一个观点,个人感觉比较有用:接口在发布后最好不要修改它,如果修改了接口就会导致之前实现接口的代码不能正常工作。我们应该创建一个新的接口来扩展旧接口,例如包换一个版本号,如X2,这是创建接口的标准方式。

IDisposable接口,提供了Dispose方法。使用这个接口的目的是就是让用户自己释放重要的稀有资源,由于GC的运行时间是不固定的,稀有资源(例如IO,数据库连接等)如果不能及时释放将会导致程序性能下降。在使用完资源之后调用Dispose方法就可以释放资源。

DisposeSample

 1 //Form类实现了IDisposable接口 2 Form form1 = new Form(); 3 //进行一些操作, 然后Dispose释放资源 4 form1.Dispose(); 5  6 //另一种使用IDisposable的方式 7 //注意括号里必须是实现IDisposable的类 8 using(Form form1 = new Form()) 9 {10       //进行一些操作, 之后C#会自己调用Dispose方法释放资源11 }

Dispose方法有一种通用的实现方式:

DisposeImplementionSample

 1 public void Dispose() 2 { 3       Dispose(true); 4       //GC调用对象的Finalize方法会损失性能, 因此自己释放了资源就不用GC再次释放了, 执行下面的语句就是为了这个目的 5       GC.SuppressFinalize(this); 6 } 7     // Dispose(bool disposing) 执行分两种不同的情况. 8     // 如果disposing 等于 true, 手动释放 9     // 如果disposing 等于false, 方法已经被终结器 finalizer 从内部调用过10 protected virtual void Dispose(bool disposing)11 {12       if(disposing)13       {14             //执行手动释放15       }16 }

关于Dispose,GC等内容还很多,听说CLR via C#里面讲得十分详细,等看过之后再与大家分享。

继承

没什么好说的,OOP的基本概念,需要注意的是C#提供了virtual,override和new关键字来处理继承成员(不只是方法,属性字段也可以),他们之间的关系需要搞清楚。只有virtual成员才能被override,如果virtual成员在派生类中有对应的override成员,那么编译器会自动使用派生类的成员,称为多态,否则始终使用基类成员:

InheritSample

 1 interface IPerson 2 { 3       void Hello(); 4       void Bye(); 5 } 6 class Person : IPerson 7 { 8       public void Hello() 9       {10             Console.WriteLine("Hello, person");11       }12 13       public virtual void Bye()14       {15             Console.WriteLine("Bye, person");16       }17 18       //如果没有下面两个方法,那么上面两个方法会被编译器当做对接口的实现,称为隐式实现,下面的称为显示实现19       void IPerson.Hello()20       {21             Console.WriteLine("Hello, iperson");22       }23 24       void IPerson.Bye()25       {26             Console.WriteLine("Bye, iperson");27       }28 }29 30 class A : Person31 {32       //隐藏了基类Person的Hello,VS会提示使用new来显示隐藏33       public void Hello()34       {35             Console.WriteLine("Hello, a");36       }37 38       //隐藏了基类Person的Bye,VS会提示使用new来显示隐藏39       public void Bye()40       {41             Console.WriteLine("Bye, a");42       }43 }44 45 class B : Person46 {47       public new void Hello()48       {49             Console.WriteLine("Hello, b");50       }51 52       public override void Bye()53       {54             Console.WriteLine("Bye, b");55       }56 }57 58 class Program59 {60       static void Main(string[] args)61       {62             IPerson[] people = new IPerson[3];63             people[0] = new Person();64             people[1] = new A();65             people[2] = new B();66             foreach (IPerson person in people)67             {68                   person.Hello();69                   person.Bye();70             }71             foreach (Person person in people)72             {73                   person.Hello();74                   person.Bye();75             }76             Console.ReadLine();77       }78 }

一些补充

补充一下,之前一篇文章提到的partial类,其实还有partial方法,partial方法必须是private,且不能是virtual,override,abstract,new,sealed和extern,最后,partial方法的参数不能是out,但可以是ref。partial方法在一个partial类中定义,但不实现,在另一个partial类中实现,如:

PartialMethod

 1 partial class MyClass 2 { 3       partial void DoSthElse(); 4  5       void DoSth() 6       { 7             Console.WriteLine("Do sth start."); 8             DoSthElse(); 9             Console.WriteLine("Do sth end");10       }11 }12 13 partial class MyClass14 {15       partial void DoSthElse()16       {17             Console.WriteLine("Do sth else.");18       }19 }

如果删除掉partial方法的实现或者该partial类,那么那句DoSthElse的调用就不会被编译,这就是partial方法用处。在自动生成的代码中,自动生成一个partial方法由用户来实现,这样可以略微提供性能。说道这里,再思考一下为什么partial方法为什么不能有返回值呢?大家可以想一想(提示:如果有的话,在使用返回值的时候会发现什么?)

VS的类图编辑器还不错,轻量级,而且也有反向工程,使用比较简单,图形看上去也比Rose,PowerDesigner之流漂亮,而且在VS里集成,用不着再开一个进程啦~

嗯,差不多就这样了,希望大家多提意见,有问题也可以一起讨论,多多交流。

转载于:https://www.cnblogs.com/applepie/archive/2011/10/01/cshape_study_2.html

从零开始学习C# 2相关推荐

  1. 从零开始学习 webservice第一集,java webservice简单实例入门教程

    现在从零开始学习webservice 概念自己百度搜,总之,webservice就相当于一个接口,就像你走进了一家售货店,你不需要知道这家店怎么卖给你东西,你拿着钱去,说我要一包玉溪,人家就会给你返回 ...

  2. python新手教程 从零开始-Python零基础从零开始学习Python十分钟快速入门

    原标题:Python零基础从零开始学习Python十分钟快速入门 学习Python的,都知道Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.Python是一种动态解释型的 ...

  3. python零基础难学吗-如何从零开始学习Python,零基础学python难吗

    Python并不难学,它诞生至今已经过25个年头,但相对于其他语言,它更加易学.易读,非常适合快速开发,Python编程简单直接,更适合初学编程者. 那么,如何从零开始学习python呢? 可以分为这 ...

  4. python自学多久可以找到工作-25岁从零开始学习python还能找到工作吗?

    相信近期大家经常可以看到培训机构推出python相关的课程,随着人工智能技术逐渐进入大众的生活,这种编程语言以简单.应用广泛的优势,成为了进入人工智能领域的条件之一.对于精通python开发的人,在职 ...

  5. python语言怎么学-如何从零开始学习Python,python语言编程入门

    Python并不难学,它诞生至今已经过25个年头,但相对于其他语言,它更加易学.易读,非常适合快速开发,Python编程简单直接,更适合初学编程者. 那么,如何从零开始学习python呢? 可以分为这 ...

  6. 从零开始学习hadoop之发行版选择

    从零开始学习hadoop之发行版选择 经常会看到这样的问题:零基础学习hadoop难不难?有的人回答说:零基础学习hadoop,没有想象的那么难,也没有想象的那么容易.看到这样的答案不免觉得有些尴尬, ...

  7. 从零开始学习OpenGL ES之五 – 材质

    从零开始学习OpenGL ES之五 – 材质 作者: iPhoneGeek 爱疯极客 09-Jan-10 iPhone Development 浏览次数: 411 |  评论 ↓ Tweet Shar ...

  8. 从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件

    本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...

  9. 从零开始学习jQuery (十) jQueryUI常用功能实战

    本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...

  10. 从零开始学习jQuery (九) jQuery工具函数

    本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...

最新文章

  1. 一套iOS面试题解答
  2. 深度学习小技巧(二):如何保存和恢复scikit-learn训练的模型
  3. Dapper.NET——轻量ORM
  4. mysql 最短路经_poj 3613 Cow Relays 经L边的最短路 | 学步园
  5. 使用Android Studio 进行NDK开发和调试
  6. 怎么做数据可视化大屏?从设计到上线,一般用这3类工具
  7. 字符转 ASCII 码
  8. 将多个Excel工作簿合并到一个Excel工作簿中
  9. Vue3.0.0-beta.1 今天它来了!!!
  10. 快手亮相第七届全球数字营销峰会,以全域内容营销驱动商业新增长
  11. 2022数据库系统工程师 下午 试题三 真题答案
  12. n个元素进栈,共有多少种出栈顺序?
  13. opencv报错:(depth == CV_8U || depth == CV_32F)
  14. Codeforces Round #768 (Div. 1)(A-C)
  15. debian安装离线源
  16. 【论文夜读】陈天琦神作Neural Ordinary Differential Equations(NuerIPS2018最佳paper)
  17. 切分数组--荷兰国旗问题
  18. 将D盘多余空间分配给C盘
  19. TabLayout自定义选择背景滑块
  20. 配电网分布式电源和储能选址定容 以配电网总成本最低为目标函数,其中包括年运行成本

热门文章

  1. 使用dom4j解析XML文件
  2. [C++] 用Xcode来写C++程序[6] Name visibility
  3. iPhone与Android手机 各个型号的UserAgent
  4. YII CRUD 例子
  5. 最长公共子字符串(动态规划)
  6. Java PECS
  7. Pandas库(1):DataFrame类
  8. jdk1.8之HashMap
  9. 使用request简单爬虫
  10. Streams全库复制