随笔分类 -  【C#】

C#
摘要:转换操作符为类之间引入了一层“替换性(substitutability)”。“替换”意味着一个类的实例可以被替换为另一个类的实例。这对我们来说可以是一种好处:一个派生类的对象可以被当做一个基类对象来使用。 阅读全文
posted @ 2008-11-01 18:23 瞪着你的小狗 阅读(553) 评论(0) 推荐(0)
摘要:ICloneable 听起来是个好主意:可以为那些支持复制的类型实现ICloneable接口。如果不想支持复制,那就不要实现它。但是我们的类型并非活在真空中。让一个类型支持ICloneable接口会影响它的派生类。一旦类型支持ICloneable接口,那么它所有的派生类也都必须支持它。而且,其所有成员类型也都要支持ICloneable接口,或者有其他创建复制的机制。最后,当我们设计的类型包含交织成网状的对象时,支持深复制将变得很困难。 ICloneable接口在其官方的定义里很巧妙地绕过了这个问题,其定义如下:ICloneable接口或者支持深复制(deep copy),或者支持浅复制(shallow copy)。浅复制指的是新对象包含所有成员变量的副本,如果成员变量为引用类型,那么新对象将和原对象引用同样的对象。 阅读全文
posted @ 2008-10-31 10:55 瞪着你的小狗 阅读(581) 评论(1) 推荐(0)
摘要:有时候,我们的类型需要排序关系来支持它们在集合中的排序和搜索。.NET框架定义了两个接口来描述类型的排序关系:IComparable和IComparer。IComparable接口定义了类型的自然排序方式。IComparer则为类型提供了另外的排序方式。我们可以为类型实现各种关系操作符(、=)来提供特定于类型的比较操作,从而避免接口实现所带来的运行时开销。本条款讨论如何通过两个接口IComparable和IComparer,来为类型实现排序关系,从而支持使用.NET框架对我们的类型进行排序,并帮助其他用户通过这些操作获取最佳的性能。 阅读全文
posted @ 2008-10-30 18:55 瞪着你的小狗 阅读(778) 评论(1) 推荐(0)
摘要:持久化(persistence)是类型的一个核心特性。这种特性往往是在我们忽略支持它们的时候,才会被注意到。如果我们的类型没有正确地支持序列化(serialization),那么其他开发人员在使用我们的类型作为成员或者基类的时候将有许多工作要做。他们必须自己实现这样的标准特性。如果不访问类型的私有实现细节,要想为类型正确实现序列化几乎是不可能的。如果我们自己不支持序列化,让类的用户来添加序列化支持将会很困难,甚至根本做不到。 阅读全文
posted @ 2008-10-30 10:16 瞪着你的小狗 阅读(849) 评论(0) 推荐(0)
摘要:和命令式编程相比,声明式编程可能是一种更简单、更精炼的描述软件程序行为的方式。声明式(declarative)编程意味着使用声明、而非指令的方式来定义程序的行为。和许多其他程序语言一样,C# 中绝大多数编程都是命令式(imperative)编程:通过编写方法来定义程序的行为。通过使用特性(attribute),我们也可以在C#中实现声明式编程。我们可以将特性应用在类、属性、数据成员或者方法上,.NET运行时则会为我们添加适当的行为。声明式编程更易于实现、阅读和维护。 阅读全文
posted @ 2008-10-29 16:05 瞪着你的小狗 阅读(929) 评论(3) 推荐(0)
摘要:大家可能认为只读属性就只能读取,调用者不可能更改属性值。可惜的是,并非所有情况都如此。如果我们创建的属性返回了一个引用类型,那么调用者就可以访问该对象的公有成员,包括那些修改属性状态的成员。 阅读全文
posted @ 2008-10-28 18:34 瞪着你的小狗 阅读(1264) 评论(0) 推荐(0)
摘要:综上所述,我们使用事件来定义类型中的外发接口,任意数量的客户对象都可以将自己的处理器登记到事件上,然后处理它们。这些客户对象不需要在编译时存在。事件也不必非要有订阅者才能正常工作。在C#中使用事件可以对发送者和可能的通知接受者进行解耦。发送者可以完全独立于接收者进行开发。事件是一种广播类型行为信息的标准方式。 阅读全文
posted @ 2008-10-27 18:37 瞪着你的小狗 阅读(556) 评论(2) 推荐(0)
摘要:那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言,因此对委托的理解不是很深,对于委托可以简单的从字面去理解,即“委托别人去执行某些操作”,也就是说执行一个操作,而这个操作过程自身并不知道,只是委托过来让你去执行而已。 阅读全文
posted @ 2008-10-26 13:15 瞪着你的小狗 阅读(898) 评论(1) 推荐(0)
摘要:这样的改写,既保留接口的完整性,同时代码比较直观,接口实现是接口实现,虚函数重载是虚函数重载,两者是分离的。不过相对于前两个虚函数实现方法,这一个方法需要编写的代码要相对多一些,效率略低(因为调用接口方法需要调用两个函数)。 阅读全文
posted @ 2008-10-26 13:12 瞪着你的小狗 阅读(817) 评论(0) 推荐(0)
摘要:.Net提供了接口,这个不同于Class或者Struct的类型定义。接口有些情况,看似和抽象类一样,因此有些人认为在.Net可以完全用接口来替换抽象类。其实不然,接口和抽象类各有长处和缺陷,因此往往在应用当中,两者要结合来使用,从而互补长短。 阅读全文
posted @ 2008-10-26 13:07 瞪着你的小狗 阅读(435) 评论(0) 推荐(0)
摘要:第一部分是语言使用的基础,而这是使用语言的基本功,也是平常最不注意的,养成好的习惯,有利于后期水平提高。第二部的主题在于资源管理,.Net编写的程序以托管程序居多,但是并不意味着可以不注意细节,合理的使用.Net提供的便利,加上好的习惯,有利于程序效率提高。 阅读全文
posted @ 2008-10-19 12:07 瞪着你的小狗 阅读(1333) 评论(9) 推荐(1)
摘要:对于托管程序来说,非托管资源来说,需要手动来释放,否则会造成资源泄漏,如果放到析构函数去完成,但是GC调用对象的析构函数时机并不确定,对于资源释放并不及时。换句话说析构函数只是保障资源不被泄漏的方法,但不是最好的方法。比较好的方法,就是使用.Net的IDisposable接口提供的Dispose方法来进行释放。 阅读全文
posted @ 2008-10-19 12:05 瞪着你的小狗 阅读(621) 评论(0) 推荐(0)
摘要:为了便于文章的开展,首先介绍装箱(Boxing)和拆箱(Unboxing)这两个名词。.Net的类型分为两种,一种是值类型,另一种是引用类型。这两个类型的本质区别,值类型数据是分配在栈中,而引用类型数据分配在堆上。那么如果要把一个值类型数据放到堆上,就需要装箱操作;反之,把一个放在堆上的值类型数据取出来,则需要进行拆箱操作。 阅读全文
posted @ 2008-10-19 08:43 瞪着你的小狗 阅读(623) 评论(0) 推荐(0)
摘要:对于.Net所写一般程序来说,都属于托管程序,内存的释放和回收是由Garbage Collector完成。但是相对于栈上内存操作而言,GC回收堆上的内存,会消耗更多的CPU时间。 阅读全文
posted @ 2008-10-19 08:36 瞪着你的小狗 阅读(650) 评论(0) 推荐(0)
摘要:很明显,Dispose方法是一个外部方法,系统并不会帮你调用。为了尽早释放对象所占用的资源,所以需要保证Dispose方法能尽早被执行。那么在.Net中提供了一个比较简便的方法,就是对于实现了IDisposable接口的类型对象提供了using语句。 阅读全文
posted @ 2008-10-19 08:33 瞪着你的小狗 阅读(1242) 评论(0) 推荐(0)
摘要:在写程序的时候,往往会出现为一个类型提供不同场景的构造函数,可能大多构造函数比较相似,而C#中又不允许缺省参数,因此构造函数的编写无疑是一个重复工作。但是使用Copy和Paste来完成构造函数的编写,有时候很难达到统一,尤其是当成员发生变化的时候。因此比较常见的替换方法就是为构造函数提供一个统一的成员函数来完成初始化工作。 阅读全文
posted @ 2008-10-18 21:32 瞪着你的小狗 阅读(455) 评论(0) 推荐(0)
摘要:编写程序的时候难免要使用到静态成员,由于静态成员的访问是脱离类型对象的,所以使用非静态构造函数,私有方法或者一些其他方法都是不合理的。.Net提供了成员初始化语句和静态构造函数来初始化静态成员。 阅读全文
posted @ 2008-10-18 21:29 瞪着你的小狗 阅读(567) 评论(0) 推荐(0)
摘要:对于类型第一个实例的构造过程大致如下:1. 分配静态成员的内存空间,此时空间存储数据为0;2. 执行静态成员的初始化语句;3. 执行基类的静态构造函数;4. 执行类型的静态构造函数;5. 分配成员的内存空间,此时空间存储数据为0;6. 执行成员的初始化语句;7. 执行相应的基类构造函数;8. 执行类型的构造函数。 阅读全文
posted @ 2008-10-18 21:23 瞪着你的小狗 阅读(418) 评论(0) 推荐(0)
摘要:循环语句是编程的基本语句,在C#中除了沿用C语言的循环语句外,还提供了foreach语句来实现循环。那么我要说的就是,在循环操作中尽量使用foreach语句来实现。 阅读全文
posted @ 2008-10-17 15:16 瞪着你的小狗 阅读(517) 评论(0) 推荐(0)
摘要:GetHashCode函数,看了它的名字就知道它会被用在哪里。没错,这个函数一般是在操作HashTable或者Dictionary之类的数据集的时候被调用。每个类型,不管是值类型还是引用类型,都提供这个基本函数,同样也可以像重写ToString或者Equals函数一样去重写它。 阅读全文
posted @ 2008-10-17 15:05 瞪着你的小狗 阅读(1205) 评论(1) 推荐(0)