C#入门(2)

Exception

基本异常的核心成员:

System.Exception Property Meaning
Data read-only,实现了IDirectory接口的一些键值对,来描述额外的或者是程序员定义的信息,默认生成的是空的
HelpLink 一个指向帮助文档或者站点的URL,get or set
InnerException read-only,给出引发当前异常信息的异常,之前的异常通常是通过构造函数的参数传递的,不是virtual的
Message read-only,给出error的信息,该信息也是通过构造函数的参数传递的
Source 给出引发异常的程序集或者对象的信息,get or set
StackTrace read-only,给出异常信息的传递链
TargetSite read-only,给出引发异常的方法的具体信息

定义自己的异常类,必须继承自System.Exception/System.ApplicationException,最好都以Exception结尾,这样比较符合.Net的命名习惯.

继承得到的子类可以将例如string类型的值,传递给父类的Message属性,仅需要在子类的构造函数中将string类对应的值传入到父类base的构造函数中,因为父类的构造函数中有三个特殊的,一个对应string的Message,一个对应Exception的inner exception,还有一个对应自己定义类型的序列化的类型.

[Serializable]
public class CarIsDeadException : ApplicationException
{
public CarIsDeadException() { }
public CarIsDeadException(string message) : base( message ) { }
public CarIsDeadException(string message,
System.Exception inner)
: base( message, inner ) { }
protected CarIsDeadException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base( info, context ) { }
}
// Any additional custom properties, constructors and data members...

标准的继承Exception的子类在vs中可以打exception,tab,有代码提示.

多级捕捉也是把最特定性的放前面,一般性的放最后.但是也支持catch后面不接参数,虽然不提倡使用.因为无法得到异常信息.当然在catch中也可以重新throw,但是最好有外层的callback,否则只能由CLR,runtime来接受异常.直接会崩溃.

如果在catch中再次出现异常,如请求了网络或者文件读写,可以在catch嵌套抛出异常,不过还是要在外面接受异常,

catch (CarIsDeadException e)
{
try
{
FileStream fs = File.Open(@"C:\carErrors.txt", FileMode.Open);
...
}
catch (Exception e2)
{
// Throw an exception that records the new exception,
// as well as the message of the first exception.
throw new CarIsDeadException(e.Message, e2);
}
}

注意这里是在原有的异常类型里增加一个参数得到的新的异常抛出,当然外面也应该处理.

Finally是一定要执行的语句.

Interface

.Net中的Interface都带着前缀I.

接口和抽象类的区别:抽象类还是要定义各种构造函数,域类型值,以及部分实现了的函数;但是接口只是定义了多态的函数没有其他以上. 另外,抽象类的继承只能使得子类实现一种功能(单继承,如果此时没有接口继承的话),难以同时拥有多种功能.

接口不能有数据域,即不能有单独的变量,只有方法,但是可以定义属性.同时也可以包含事件和索引.

结构和类都可以实现接口.

运行时得到类是否实现了某个接口可以使用显式地转换,转换为接口类型.(这也解释了为什么Executor类会转变成为ExecutorService,因为这样可以马上被别人看出来这是实现了线程池的类.)

可以使用as和is来判断是不是实现了某种接口,前者不是的话返回一个null,后者则返回一个false.

在使用接口时,如果多个接口共有一个方法,那么在实现时,其实是所有的接口公用了一个方法,应该显式地声明使用的是哪个接口,用"接口.方法"来显式实现.

接口中没有访问限制,所有默认都是public和abstract的.

接口可以多继承,具体的实现决定于程序员,首先所有父类特有的方法都必须继承和实现,而对于两者定义的相同方法,则选择性的实现,如果是要实现两个版本,就和前面显式实现一样.

IEnumerable和IEnumerator接口,前者仅仅有一个方法,返回一个IEnumerator类型的对象.后者是具体实现了选择下一个的功能.

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
} // This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
bool MoveNext (); // Advance the internal position of the cursor.
object Current { get;} // Get the current item (read-only property).
void Reset (); // Reset the cursor before the first member.
}

由于实现了IEnumerable和IEnumerator的分离,所以在具体实现的时候只要在Collection中找到实现了IEnumerator的就可以简化实现.使用显式实现接口可以隐藏对象级别的接口实现.

ICloneable和yield关键字:yield和python中类似,返回一个值并且从函数的开头开始执行.所以也可以使用yield和自己显式定义的函数一起实现IEnumerator接口.当深复制的时候注意一件事,如果需要一个不同的GUID(globally unique identifier description),则包含一个System.GUID的对象即可.不过注意更新clone().

ICompareable接口:实现Compareto(),和传统的一样,返回正值,0或者负值,作为判断的标识.

IComparer接口:实现Compare(),可以接受多个参数,主要是接受两个Object,可以任意的按照某一属性比较.现在也可以使用一个静态属性来表示实现某一种接口.如:

public class Car : IComparable
{
//Property to return the PetSortByName
public static ICompare SortByName{
get {return (ICompare) new PetNameCompare();}
}
}
//这里的PetNameCompare是一个类;
// Sorting by pet name made a bit cleaner.
Array.Sort(myAutos, Car.SortByPetName);

Collection和Genetic

在.Net1.0之前没有泛型,因此所有的Collection都需要特殊的自定义函数来添加和减少.常用的几种见下表:

System.Collection Class Meaning Key Interface Implementation
ArrayList Represents a dynamically sized collection of objects listed in sequential order. IList , ICollection, IEnumerable , and ICloneable
BitArray Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0). ICollection, IEnumerable,and ICloneable
Hashtable Represents a collection of key/value pairs that are organized based on the hash code of the key. IDictionary, ICollection,IEnumerable, and ICloneable
Queue Represents a standard first-in, first-out (FIFO) collection of objects. ICollection, IEnumerable, and ICloneable
SortedList Represents a collection of key/value pairs that are sorted by the keys and are accessible by key and by index. IDictionary, ICollection, IEnumerable, and ICloneable
Stack A last-in, first-out (LIFO) stack providing push and pop (and peek) functionality. ICollection, IEnumerable, and ICloneable

需要注意,现在一般不使用none genetic的类,而应该使用对应的genetic版本.还有一部分是Syetem.Collection.Specialized,也都是no generic其中以下四个用的较多:

System.Collection.Specialized Meaning
HybridDictionary 实现了IDictionary接口,在数量小的时候用ListDictionary,大的时候转换成为Hashtable
ListDictionary 用单链表连接的字典
StringCollection 大规模使用string时有优化
BitVector32 32位的内存为一个单元,存储小整型或者是Boolean值

需要知道在使用nongenertic时,里面自动装箱和解箱,但是要注意解箱的时候返回的是一个Object类型,需要自己在显式转换.

所以非泛型的容器有两点问题:

  1. 装箱和解箱的性能问题.
  2. 类型安全问题,有可能出现不恰当的类型转换.

泛型容器:

仅有class, struct, interface, delegates可以使用泛型,而枚举类型不可以.

常用的泛型容器:

System.Collection.Generic Support Key Interface Meaning
Dictionary<TKey, TValue> ICollection<T>,IDictionary<TKey, TValue>,IEnumerable<T> This represents a generic collection of keys and values.
LinkedList<T> ICollection<T>, IEnumerable<T> This represents a doubly linked list.
List<T> ICollection<T>, IEnumerable<T>,IList<T> This is a dynamically resizable sequential list of items.
Queue<T> ICollection (Not a typo! This is the nongeneric collection interface) , IEnumerable<T> This is a generic implementation of a first-in,first-out (FIFO) list.
SortedDictionary<TKey,TValue> ICollection<T>,IDictionary<TKey, TValue>,IEnumerable<T> This is a generic implementation of a sorted set of key/value pairs.
SortedSet<T> ICollection<T>, IEnumerable<T>,ISet<T> This represents a collection of objects that is maintained in sorted order with no duplication.
Stack<T> ICollection (Not a typo! This is the nongeneric collection interface) , IEnumerable<T> This is a generic implementation of a last-in, first-out (LIFO) list.

泛型容器的初始化和普通的类型同,也支持大括号的初始化方式,在C++11中叫做初始化列表.也支持在容器内初始化对象,即嵌套的初始化.对于容器的初始化需要注意:

List&lt;T&gt; alist = new List&lt;T&gt;(){.......}

这里的小括号没有也可以,但是为了统一,仍然是先调用初始化函数再初始化列表.统一加().

List,Queue,Stack都没什么特别的,需要注意的是SortSet等有关Sort的需要先写一个类实现ICompare接口,然后将其对象作为参数传递到容器的构造函数中.

System.Collections.ObjectModel:

是一个比较小的命名空间,有一些附加的类型,其中有两个比较重要:

System.Collections.ObjectModel Type Meaning in Life
ObservableCollection<T> Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
ReadOnlyObservableCollection<T> Represents a read-only version of ObservableCollection<T>.

这里就是实现了观察者模式,当容器有任何变化时,都会有事件触发,需要实现一个观察者的代理(协议),具体到协议的一部分再介绍.

// Wire up the CollectionChanged event.
people.CollectionChanged += people_CollectionChanged;

其实有很多需要使用泛型的原因还在于需要考虑装箱解箱的效率(不需要堆和栈之间的拷贝),以及函数重载的不足.

泛型容器的构造函数:在泛型中可以使用default关键词,这里就是default就有多重含义.由于泛型中无法得到具体的类型参数的初始值,因此初始值对于数值型是0,对于引用型是null.

// Reset fields to the default value of the
// type parameter.
public void ResetPoint()
{
xPos = default(T);
yPos = default(T);
}

这里的default就保证了得到初始值.

对类型参数的约束:使用where对type进行约束,见下表:

Generic Constraint Meaning in Life
where T : struct The type parameter <T> must have System.ValueType in its chain of inheritance (i.e., <T> must be a structure).
where T : class The type parameter <T> must not have System.ValueType in its chain of inheritance (i.e., <T> must be a reference type).
where T : new() The type parameter <T> must have a default constructor. This is helpful if your generic type must create an instance of the type parameter because you cannot assume you know the format of custom constructors. Note that this constraint must be listed last on a multiconstrained type.
where T : NameOfBaseClass The type parameter <T> must be derived from the class specified byNameOfBaseClass.
where T : NameOfInterface The type parameter <T&gt must implement the interface specified by NameOfInterface. You can separate multiple interfaces as a comma-delimited list.

注意其中的new()必须放在最后.如果有多个Type参数则必须使用多个where语句.

C#入门(2)的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  3. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  4. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  5. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  6. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  7. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  8. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  9. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  10. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. 动态加载dll

    extern "C" MMUPDATENOTIFY_IMPEXP bool _cdecl NotifyThrift(char* chThriftIp, char* chPor) H ...

  2. POJ 3067【树状数组】

    题意: 给你两行数字,n个m个,然后给你k条线直接把两个数连起来,问有多少个交叉的 思路: 假定上一行是起点,下一行是终点. 把路按照起点从大到下排序, 然后可以直接对每条路查询,这条路目前的交叉数, ...

  3. Forward Rendering 正向渲染

    Forward Rendering 正向渲染        正向渲染一个基于着色器的渲染路径.它支持逐像素计算光照(包括法线贴图和灯光Cookies)和来自一个平行光的实时阴影.在默认设置中,少数最亮 ...

  4. C#、Unity网络通信中基于字节码的自定义协议解码,C#版ByteBuffer

    http://www.oschina.net/code/snippet_42170_37516 C#.Unity基于字节的网络通信中字节码解析类,类似java中的ByteBuffer,不过这个实现是参 ...

  5. 51nod1475(贪心&枚举)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1475 题意:中文题诶- 思路:看懂题意后,首先想到的是贪心: ...

  6. bzoj 3158: 千钧一发【最小割】

    这个条件非常妙啊,奇数和奇数一定满足1,因为\( (2a+1)^2+(2b+1)^2=4a^2+4a+4b^2+4b+2=2(2(a^2+a+b^2+b)+1) \)里面这个一定不是平方数因为除二后是 ...

  7. [Xcode 实际操作]二、视图与手势-(4)给图像视图添加边框效果

    目录:[Swift]Xcode实际操作 本文将演示给图片添加颜色相框 import UIKit class ViewController: UIViewController { override fu ...

  8. 在mpvue框架中使用Vant WeappUI组件库的注意事项

    1如何引入组件库 有两种方法 1 npm下载 2 下载代码,下面介绍第二种方法. 在gitHub上, 链接如下 https://github.com/youzan/vant-weapp 首先在自己项目 ...

  9. 基于java开发的在线题库系统tamguo

    简介 探果网(简称tamguo)是基于java开发的在线题库系统,包括 在线访问 后台运营 会员中心 书籍中心 管理员账号:system 密码:123456 因为线上数据和测试数据没有做到隔离,作者已 ...

  10. ACM之路

    从10月我刚接触到acm竞赛,到现在2017年2.20接近4个月的时间,我才刷到200道题.在刷题的过程中,我曾遇到困难,我也从一次性就a过,但是有时候会想到放弃.不过既然已经踏进来一只脚,还不如就好 ...