privatevoid ListChanged(object sender, EventArgs e) {
Console.WriteLine(\); }
publicvoid Detach() {
List.Changed -= newChangedEventHandler(ListChanged); List = null; } }
classTest {
publicstaticvoid Main() {
ListWithChangedEvent list = newListWithChangedEvent();
EventListener listener = newEventListener(list);
list.Add(\); list.Clear(); listener.Detach();
Console.ReadLine(); } } }
11.internal修饰符
此修饰符定义的方法或者类,允许在同一个命名空间内被调用或访问。 代码实例:
namespace InterfaceTest {
classDllTest {
publicstaticvoid Main() {
FatherClass fc = newFatherClass(1188); InFatherClass ifc = newInFatherClass(1199);
Console.ReadLine(); } }
//public class FatherClass //{
// public int a;
// public FatherClass(int a) // {
// this.a = a;
// Console.WriteLine(\共有类构造:{0}\// } //}
//internal class InFatherClass //{
// public int a;
// public InFatherClass(int a) // {
// this.a = a;
// Console.WriteLine(\内部类构造:{0}\// } //} }
将注释的部分写在另一个类中,利用命令csc /t:library /out:DllTest.dll DllTest.cs 打成dll文件,再将这个文件添加到项目的引用,运行会提示InFatherClass无法访问。但如果把注释清除在运行,就可以了。
12.一个Email事件处理的实例
主要思想在于对MailManager类的具体的处理方法,都由Fax类来完成,而不需要去关注MailManager类作为上层处理事件的具体处理方法。而这种事件之间的传递就由委托事件处理来完成。 代码如下:
namespace InterfaceTest {
classEmailTest { }
publicclassMailManager {
//定义事件委托类
publicdelegatevoidMailMagEventHandler(Object sender, MailMagEventArgs args);
//定义事件参数类
publicclassMailMagEventArgs : EventArgs {
publicreadonlyString from, to, subject, body;
public MailMagEventArgs(String from, String to, String obj, String body) { this.from = from; this.to = to; this.subject = obj; this.body = body; } }
//定义事件成员
publiceventMailMagEventHandler MailMag;
//定义触发事件的方法
protectedvirtualvoid OnMailMag(MailMagEventArgs e) {
//判断事件成员MailMag上是否绑定了事件处理方法 if (MailMag != null) {
MailMag(this, e); } }
//接收触发事件的信息和方法
publicvoid SimulateArrivingMag(String from, String to, String sub, String body) { //创建事件参数
MailMagEventArgs e = newMailMagEventArgs(from, to, sub, body); OnMailMag(e); } }
//Fax类对MailManager类进行上层的管理,包括 publicclassFax {
publicstring FaxID;
public Fax(MailManager mm) {
//创建一个事件委托对象,并把事件处理方法FaxMag注册到MailMag事件 成员上 mm.MailMag+=newMailManager.MailMagEventHandler(FaxMag); }
//事件处理方法
privatevoid FaxMag(Object sender, MailManager.MailMagEventArgs e) {
//sender表示触发事件的对象,即MailManager对象
//e表示事件参数,包含与事件有关的信息,如信息的来源和主题等 Console.WriteLine(\ + FaxID);
Console.WriteLine(\, e.from, e.to, e.subject, e.body); }
//取消注册事件的方法
publicvoid Unregister(MailManager mm) {
mm.MailMag -= newMailManager.MailMagEventHandler(FaxMag); } }
publicclassMailApp {
staticvoid Main(string[] args) {
Console.WriteLine(\); Console.WriteLine(\代理与事件的应用\); Console.WriteLine(\);
MailManager mm = newMailManager();
Fax f1 = newFax(mm); //创建传真机等接收器的对象 f1.FaxID = \;
mm.SimulateArrivingMag(\, \, \, \); f1.Unregister(mm); Fax f2 = newFax(mm);
f2.FaxID = \;
mm.SimulateArrivingMag(\, \, \, \); Console.ReadLine(); } } }
13.几个的区别
1)C#类和接口的区别
接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念。而类是负责功能的具体实现。
在类中也有抽象类的定义,抽象类与接口的区别在于:
抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化。
但接口是一个行为的规范,里面的所有东西都是抽象的。
一个类只可以继承一个基类也就是父类,但可以实现多个接口。
PS:接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设计原则以及设计模式的使用中,无不体现作为一个接口的使用好处,最直接的就是设计原则中OCP(开放封闭原则),我们使用接口,而不需要关心他的具体实现,具体实现的细节变化也无关客户端(使用接口的类)的使用,对与扩展是开放的,我们可以另写一个接口的实现来扩展当前程序,而不影响上层的使用,但对修改是封闭的,即我们不能够再去修改接口的定义,当然这个“不能够”是指在规范原则上不应该这么做。
2)抽象类和接口的区别
抽象类(abstract class)可以包含功能定义和实现,接口(interface)只能包含功能定义。抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定,因此反映的是事物的外部特性。分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”,为外部提供调用或功能需要扩充时优先使用接口。
3)C#语言中,值类型和引用类型有何不同?
值类型和引用类型的区别在于,值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。