委托(virtual、override)

关于委托的实现

为了实现方法的参数化,学者们提出了委托的概念。

委托是一种引用方法的类型,即委托是方法的引用,一旦为委托分配了方法,委托将与该方法具有完全相同的行为;另外,.NET中为了简化委托方法的定义,提出了匿名方法的概念。本篇技术内容将对委托和匿名方法进行讲解。

委托

C#中的委托(Delegate)是一种引用类型,该引用类型与其他引用类型有所不同。在委托对象的引用中存放的不是对数据的引用,而是存放对方法的引用,即在委托的内部包含一个指向某个方 法的指针。通过使用委托把方法的引用封装在委托对象中,然后将委托对象传递给调用引用方法的代码。委托类型的声明语法格式如下:

修饰符 delegate 返回类型 委托名称 (参数列表)

修饰符dleate返回类型委托名称(参数列表)其中,修饰符是可选项;返回类型、关键fegae和凌托名称是必需项:列表用来指定委托所匹配的方法的参数列表,所以是可选项。一个 与委托类型相匹配的方法必须满足以下两个条件。

这二者具有相同的签名, 即具有相同的参数目,并且类型相同,顺序相同,参数的修饰符也相同。

这二者具有相同的返回值类型。委托是方法的类型安全的引用,之所以说委托是安全的,是因为委托和其他所有的C#成员一样,是一一种数据类型,并且任何委托对象都是System.Delegate的某个派生类的一一个对象 ,委托的类结构如图一所示。

从图一的结构图中可以看出,任何自定义委托类型都继承自System. Delegate类型,并且该类型封装了许多委托的特性和方法。下面通过一个具体的例子来说明委托的定义及应用。

 例:创建一个控制台应用程序,首先定义一个实例方法Add,该方法将作为自定义委托类型MyDelegate 的匹配方法;然后在控制台应用程序的默认类Program中定义一个委托类型MyDelegate ,接着在应用程序的入口方法Main中创建该委托类型的实例md,并绑定到Add方法。代码如下:

public classTestClass

{

       public int Add(int x,int y)

       {

              Return x+y;

}

}

Class Program

{

       Public delefate int MyDelegate(int x,int y);

       Static void Main(string[] args)

       {

       TestClass tc = new TestClass();

       MyDelegate md = tc.Add;

       Int intSum = md(2 , 3);

       Console.WriteLine(“运算结果是:”+intSum.ToString());

       Console.Read();

}

}

上面代码中的MyDelegate自定义委托类型继承自System.MulticastDelegate,并且该自定义委托类型包含一个名为Invoke的方法,该方法接受两个整型参数并返回一个整数值,由此可见,Invoke方法的参数及返回值类型与Add方法完全相同。实际上程序在进行委托调用时就是调用了Invoke方法,所以上面的委托调用完全可以写成下面的形式:

Int intSum = md.Invoke(2 , 3);                      //委托的调用

其实,上面的这种形式更有利于初学者的理解,上面代码的运算结构为:“运算结果是:5”。

关于virtual虚方法

在默认情况下方法、属性都是非虚拟的,而被virtual关键字修饰的父类实例方法被称为虚方法,就是说明需要再派生类中的重写、修改。被virtual关键字修饰的方法,必须有方法体,不能像抽象方法那样简写,虚方法表现如下:

Virtual public void Add()

{

      Console.WriteLine(“我是虚方法”);

}

如果要重写方法,必须使用override关键字声明,override表示覆盖(重写),派生类的方法签名和返回值类型必须要和父类相同,相同时才说明是重写。例如下:

Public override void Add()

{

      Console.WriteLine(“我是虚方法重写”);

}

如果父类的某个实例方法被virtual关键字修饰,但是派生类重写的时候没有使用override关键字修饰,此时不报错,但会发出警报。如果父类的某个实例方法被virtual修饰,而派生类并没重写,只继承了,那么通过调用派生类的输出结果就是父类的,这就让关键字override修饰得毫无作用。

Virtual关键字不能和static同用,只能据实际情况选其一,这是因为virtual修饰后就让继承重写的,而被static关键字修饰的静态方法是不能继承的,如下是一个错误例子:

static public virtual void Add()

{

      Console.WritLine(“本想重写,实现错误”)

}

同样,virtual关键字也不能同private关键字同用,因为virtual关键字是继承重写的,而private是私有的,是不能继承的,也就是,private关键字不能用于声明虚方法。如下是错误例子:

Private virtual voidAdd()

{

      Console.WriteLine(“错误用法”);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值