唐大仕 dstang2000@263.net http://www.dstang.com 第4章 C#高级特性,异常,调试 唐大仕 dstang2000@263.net http://www.dstang.com.

Slides:



Advertisements
Similar presentations
Memory Pool ACM Yanqing Peng.
Advertisements

编译原理上机实习
程設一.
C#程序设计 10软件1、2班 王槐彬 计算机工程学院.
第二章 JAVA语言基础.
Data Abstraction: The Walls
第1章 C#入门基础 Microsoft公司是这样描述C#的:“C#是从C和C++派生来的一种简单、现代、面向对象和类型安全的编程语言。C#(读做'Csharp')主要是从C/C++编程语言家族移植过来的,C和C++的程序员会马上熟悉它。C#试图结合Visual Basic的快速开发能力和C++的强大灵活的能力。”。本章将讲解使用C#语言开发的入门知识,主要介绍以下知识点。
C# 程式設計 第一部分 第1-4章 C# 程式設計 - 南華大學資管系.
程設一.
程式設計實作.
第5章 异常处理 王德俊 上海交通大学继续教育学院.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
第八章 C#高级编程.
Visual Basic 6.0 學習範本 第三章 基本資料型態.
物件導向程式設計 (Object-Oriented rogramming)
第二章 C# 基础知识.
例外處理(Exception Handling)
Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!
第3章 變數、資料型別與運算子.
DEV 331 深度探索 Microsoft Visual C# 2.0
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
本單元介紹何謂變數,及說明變數的宣告方式。
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
C++ with Managed Extensions
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
Java语言程序设计 第五部分 Java异常处理.
委派與執行緒 建國科技大學 資管系 饒瑞佶.
王豐緒 銘傳大學資訊工程學系 問題:JAVA 物件檔輸出入.
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
第3章 變數、資料型別與運算子 3-1 變數與資料型別的基礎 3-2 變數的命名與宣告 3-3 資料型別 3-4 運算式與運算子
第6章 继承和接口设计 6.1 继 承 6.2 多态性 6.3 抽象类 6.4 接口 6.5 接口在集合排序中的应用.
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
檔案讀寫與例外處理 (File IO and Exception Handling)
9.1 程式偵錯 9.2 捕捉例外 9.3 自行拋出例外 9.4 自定例外類別 9.5 多執行緒
第 十二 章 C# 中的文件处理.
异常及处理.
Java程序设计 第2章 基本数据类型及操作.
$10 可空类型.
P2P聊天工具.
Chapter 5 Recursion.
第三章 C# 基础知识.
Web Server 王宏瑾.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
Classes (2) Lecture 7.
劉崇汎 崑山科技大學 電腦與通訊系 DLL的建立與引用 劉崇汎 崑山科技大學 電腦與通訊系
第五章 介面/集合/泛型 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
C#程序设计基础 $3 成员、变量和常量.
第7章 异常处理.
Oop8 function函式.
第二章 Java基本语法 讲师:复凡.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.

第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
方法進階及物件導向基礎 Lecturer: 楊昌樺.
Java程序设计 第17章 异常和断言.
C# 匿名委派 + Lambda + Func 建國科技大學 資管系 饒瑞佶.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
對於成員(member)存取權的限制 成員的資料被毫無限制的存取,任誰都可以指定任意值給成員,Java語言為了防止這種現象的產生,規定:有一種成員的資料不能任由類別外部的任何人隨意存取。
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
第二章 Java基础语法 北京传智播客教育
Presentation transcript:

唐大仕 dstang2000@263.net http://www.dstang.com 第4章 C#高级特性,异常,调试 唐大仕 dstang2000@263.net http://www.dstang.com

本章内容 4.1 程序的组织 4.2 委托与事件 4.3 运算符重载 4.4 异常处理 4.5 Attribute 4.1 程序的组织 4.2 委托与事件 4.3 运算符重载 4.4 异常处理 4.5 Attribute 4.6 C#语言中的其他成分 4.7 程序的调试

4.1 程序的组织 名字空间 程序的逻辑组织 嵌套类型 类中嵌套类型 程序集 程序的物理组织

名字空间 1.名字空间的概念 2.名字空间的声明 3.名字空间的导入 4.使用别名 逻辑划分;避免名字冲突 namespace xxx.xxxx { } 可嵌套 3.名字空间的导入 using xxx.xxxx; 4.使用别名 using 别名 = 名字空间或类名; NamespaceUsing.cs

嵌套类型 嵌套类型的概念 嵌套类型的可访问性 类型中的类型 class A{ public class B{ public struct C{} } } new A.B.C(); 嵌套类型的可访问性 受各个层次的限制 NestedAccessibility.cs

程序集 模块(module) 程序集(assembly) 在VS.NET上引用程序集 在项目上点右键,添加引用

csc /target:mod /out:Add.mod Add.cs csc /target:mod /out:Multi.mod Multi.cs al /target:library /out: MyLibrary.dll Add.mod Multi.mod csc /target:exe /out:MyClient.exe /reference:MyLibrary.dll MyClient.cs

大致上: 委托-------函数指针 事件-------回调函数 4.2 委托与事件 大致上: 委托-------函数指针 事件-------回调函数

委托 委托的声明 委托的实例化 委托的调用 委托变量名(参数列表 ) d2(8.9) DelegateIntegral.cs public delegate double MyDelegate ( double x ); 委托的实例化 MyDelegated d2 = new MyDelegate( obj.myMethod ); 委托的调用 委托变量名(参数列表 ) d2(8.9) DelegateIntegral.cs

委托示例 DelegatePlotFun.cs

委托的合并 委托的合并----多播MultiCastDelegate 运算符 + - += -= 一个委托实例中可以“包含”多个函数 调用委托,就是调用其中多个函数 多个函数间的先后顺序是没有意义的 运算符 + - += -= 动态地增减其中的函数 提高了程序的灵活性 DelegateMultiTest.cs Delegate温度.cs

委托的转换与相等 委托的转换 委托的相等 按声明的名称判断 以下两个不能互相转换或加减 按内容(即其中“包含的函数”)来判断 delegate void D( int a ); delegate void E( int a ); 委托的相等 按内容(即其中“包含的函数”)来判断 DelegateEquals.cs

事件 事件的声明 事件的注册与移除 事件的发生 public event 委托名 事件名; 事件名 += 或 -= 事件名(参数列表) 事件名 += 或 -= 在事件所在类的外面,只能用以上两个运算符 事件的发生 事件名(参数列表) 相当于回调所注册的函数

事件与委托的关系 事件有点像委托类型的实例 事件比委托实例更复杂:事件存取器 事件一定有相关的委托类型 与委托实例一样,事件也“包含”多个函数 事件的运算符受更多限制(+=或-=) 事件比委托实例更复杂:事件存取器 修饰符 event 委托类型名 事件名 { add{ e += value; } remove{ e -= value; } } EventButtonForm.cs

使用事件的例子 网络爬虫程序中通知调用者下载开始、结束及下载进度 EventWhenDownload.cs

综合示例 使用C#多种语法要素(特别是event及Exception) 参见 BankSystem-v1-v2

csharp语言新特性与事件 C#2.0 引入泛型 C#3.0 引入Lambda及Linq C#4.0 更多的动态特性dynmaic

泛型(Generic) List<Book> books=new List<Book>(); Book book = books[0]; //以前要用强制类型转换 ArrayList books = new ArrayList(); Book book = (Book) books[0];

匿名方法 delegate(参数){ 方法体} 可以当一个匿名方法 可以被隐式转换为一个兼容的委托类型 new Thread( new ThreadStart( delegate(){ …….} ) ); 可以被隐式转换为一个兼容的委托类型 new Thread(delegate(){ …….} );

Lamda表达式 相当于匿名方法的简写 (参数)=>{语句或表达式}

Linq 常见的形式 相当于 from c in customers where c.Age>10 orderby c.Name select new {c.Name, c.Phone} 相当于 customers .Where(c=> c.Age>10) .OrderBy(c => c.Name). .Select(c => new { c.Name, c.Phone })

示例 在不同C#版本中使用delegate 参见:MethodDelegateLamda

4.3 运算符重载

运算符 使用运算符的例子 运算符有时比方法名更直观 运算符重载有一些限制 this.Location += new Size(10,10); TimeSpan diff = date2 – date1; String s1, s2; … if( s1==s2) 运算符有时比方法名更直观 如 两个复数用 a+b 比 a.Add(b)更直观 但要慎用 运算符重载有一些限制 如成对,如类型要求,如有的不能重载 更详细的内容,请参见文档

运算符的声明 一元运算符声明的形式如下: 二元运算符声明的形式如下: 类型转换运算符声明的形式如下: OperatorComplex.cs public static 类型 operator 一元运算符 ( 类型 参数名 ){ …… } 二元运算符声明的形式如下: public static 类型 operator 二元运算符 ( 类型 参数名,类型 参数名) { …… } 类型转换运算符声明的形式如下: public static implicit operator 类型 ( 类型 参数名) { …… } public static explicit operator 类型 ( 类型 参数名) { …… } OperatorComplex.cs

4.4 异常处理

异常处理 异常可以以两种不同的方式引发: 首先介绍一下throw语句。throw语句抛出一个异常的语法为: C#语句和表达式执行过程中激发了某个异常的条件,使得操作无法正常结束,从而引发异常。例如整数除法操作分母为零时将抛出一个异常。 首先介绍一下throw语句。throw语句抛出一个异常的语法为: throw expression 带有表达式的throw语句抛出的异常是在计算这个表达式时产生的。异常由try语句来处理的 try语句提供了一种机制来捕捉执行过程中发生的异常。以下是它的三种可能的形式: try-catch try-finally try-catch-finally

异常的概念 C#中的异常处理 System.Exception类 try{ } catch(Exception e){ } finally{ } System.Exception类 public Exception(); public Exception(string s); Message属性 StackTrace属性

几种常用的异常类 System.OutOfMemoryException System.StackOverflowException System.NullReferenceException System.TypeInitializationException System.InvalidCastException System.ArrayTypeMismatchException System.IndexOutOfRangeException System.MulticastNotSupportedException System.ArithmeticException System.DivideByZeroException System.OverflowException

捕获和处理异常 抛出异常 捕获异常 throw new SomeException(); try{ } catch(AException e1){ } catch(BException e2){ } catch(更一般的Exception e){ } finally{ } 注:catch{}表示捕获所有种类的异常 ExceptionIndexOutOf.cs ExceptionSimple.cs

创建用户自定义异常类 从Exception或ApplicationException继承 重抛异常 异常链接 throws; throw new Excepiton( “msg”, e ); 这里e称为内部异常 InnerException属性 使得外部能进一步知道内部的异常原因 ExceptionInner.cs

算术溢出与checked 对溢出进行检查 对溢出异常进行捕获 对整个程序 csc /checked XXXX.cs 对部分程序 针对表达式: checked(表达式) 及 uncheckd(表达式) 针对块语句: checked{……} 及 uncheckd{……} 对溢出异常进行捕获 try{ } catch( OverflowException e ) { } CheckedTest.cs

4.5 Attribute

使用Attribute的例子 用在类上的 用在方法上的 [Serializable] public sealed class String : IComparable, Icloneable, IConvertible, Ienumerable 用在方法上的 [STAThread] static void Main()

Attribute Attribute是与类、结构、方法等元素相关的额外信息, 是对元信息的扩展。 [HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)] class SomeClass { [WebMethod] void GetCustomers() { … } string Test([SomeAttr] string param1) {…} } Blue box here and on next slide

使用系统定义的Attribute 使用Attribute的一般方式 示例 在程序集、类、域、方法等前面用[]表示 可以省略“Attribute”几个字母,只写xxxxx 可以带参数 位置参数 (相当于构造方法带的参数) 命名参数(域名或属性名=值) 示例 在Main()方法使用[STAThread] 使用“过时”:AttributeObsolete.cs 使用“条件”:AttributeConditional.cs 在结构上、枚举上使用:StructLayout,Flag 在程序集级别应用Attribute [assembly: AssemblyCompany("")]

自定义Attribute 1.声明Attribute类 2.使用Attribute类 3.通过反射访问属性 AttributeHelp.cs

Attributes are classes Attached to types and members Attributes can be queried at runtime class HelpUrlAttribute : System.Attribute { public HelpUrlAttribute(string url) { … } … } [HelpUrl(“http://SomeUrl/APIDocs/SomeClass”)] class SomeClass { … } Type type = Type.GetType(“SomeClass”); object[] attributes = type .GetCustomAttributes();

4.6 C#语言中的其他成分

编译预处理 1.标识符声明 2.条件处理 3.信息报告 4.行号标记 #define定义一个标识符; #undef“取消定义”一个标识符。 #if, #elif, #else, #endif 3.信息报告 #error 和 #warning 4.行号标记 #line 行号 "文件名"

unsafe及指针 1.unsafe 2.fixed及指针 3.sizeof运算符 4.stackalloc 用于修饰类、方法等 在栈上分配的内存,而不是在堆上,因此不会担心内存被垃圾回收器自动回收。 UnsafeCopy.cs

C# And Pointers Developers sometime need total control Performance extremes Dealing with existing binary structures Advanced COM Support, DLL Import C# “unsafe” = a limited “inline C” Pointer types, pointer arithmetic Unsafe casts Declarative pinning (fixed statement) C# developers have headroom Unsafe note: Unsafe code can’t be verified, and therefore needs full trust to execute; can’t be used in a download scenario.

Unsafe Example class FileStream: Stream { int handle; [dllimport("kernel32", SetLastError=true)] static extern unsafe bool ReadFile(int hFile, void* lpBuffer, int nBytesToRead, int* nBytesRead, Overlapped* lpOverlapped); public unsafe int Read(byte[] buffer, int index, int count) { int n = 0; fixed (byte* p = buffer) { ReadFile(handle, p + index, count, &n, null); } return n; This is the first view of defining a dllimport, so it pays to discuss it here… Important point on fixed: Fixed sets a flag on the object so that it won’t be moved if a garbage collection occurs. This is very low cost, since there is no effect unless a GC occurs inside the fixed block.

其他关键字 1.lock 2. volatile 多线程程序中,lock可以将某个对象加锁

C#几个语法的小结 类型声明 类的成员

类型声明 类型声明是C#程序的主体,它可以位于名字空间中,也可以是嵌套的类型。 类型声明包括以下几种: 1) 类 class 2) 结构 struct 3) 接口 interface 4) 枚举 enum 5) 委托 delegate

类的成员 1) 常数(const) 2) 域(field) 3) 方法(method) 4) 属性(property) 它代表了与类相关的常数数据。 2) 域(field) 它是类中的变量。 3) 方法(method) 它实现了可以被类实现的计算和行为。 4) 属性(property) 它定义了命名的属性和与对这个属性进行读写的相关行为。 5) 事件(event) 它定义了由类产生的通知 6) 索引(indexer) 它允许类的实例通过与数组相同的方法来索引。

类的成员(续) 7) 运算符(operator) 8) 实例构造函数(instance constructor) 它定义了可以被应用于类的实例上的表达式运算符。 8) 实例构造函数(instance constructor) 它执行需要对类的实例进行初始化的动作。 9) 析构函数(destructor) 类的实例被清除时实现的动作(结构不能有析构函数)。 10) 静态构造函数(static constructor) 它执行对类本身进行初始化的动作。 11) 类型(type) 它代表位于类中的类型。

4.7 程序的调试

错误的种类 代码的错误通常可以分成三大类 语法错误 运行错误 逻辑错误 其中语法错误比较容易排除,也是一种低级的错误。运行错误和逻辑错误需要靠经验、调试工具以及不断的深入代码来排除。

语法错误 此类型的错误通常发生在程序员对语言本身的熟悉度不足 如if之后忘了加上大括号、For语句少了分号。还有比如定义一个变量是Student,但是在引用的时候不小心就变成studnet了。还有一种情况是调用函数错误的语法。 例如调用SubString函数少传了一个参数。使用Visual Studio.NET开发工具,多数的错误会在编辑程序的时候发现。

逻辑错误 逻辑错误(Logic Error)是指程序算法的错误,这种错误程序不会发生任何程序中断或跳出程序,而是一直执行到最后,可能有结果。但是执行结果是不对的。 如计算1到10的总数,结果应该为55,利用下面的算法。

运行时错误 运行时错误(Runtime Error)多数发生在不可预期的异常。 比如打开硬盘上的某个文件时,该文件不存在。向硬盘上写某个文件的时候,硬盘的空间不足。 由于网络阻塞得不到预期的数据等等。也有可能是用户不按正确的操作步骤而造成的错误, 如在做除法的时候除数为零,访问数组的时候,超出了可访问下标的范围,这些都是发生错误的原因。比如下面的代码。

程序调试的基本手段 断点 跟踪 监视

断点 断点 断点的属性 清除或禁用断点 用鼠标单击左边 Ctrl+B 调试|窗口|断点 Ctrl+Alt+F9 条件断点(先设置断点,右击,可编辑条件) 命中次数 清除或禁用断点 清除所有断点 Ctrl+Shift+F9

跟踪 单步执行 逐语句 F11 逐过程 F10 点右键,运行到光标处 跳出函数 Shift+F11 拖动到下一句(跳过中间一些语句)

监视 即时监视 快速监视 Ctrl+Alt+Q 自动窗口 调用堆栈 指令 调试|窗口|反汇编

练习 1.练习C#语言中的几个高级特性 2.练习异常的处理 3.练习调试 参见ch04下的示例 参见forDebug下的示例 while循环的跟踪 数组的跟踪(筛法求素数) 构造方法执行过程的跟踪 一个dotNET BUG的跟踪

进一步阅读 电子稿 《C#语言高级特性.doc》 文章 《The Code Project – Exception Handling Best Practices in _NET - _NET.htm》

问题与讨论 dstang2000@263.net