在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数。这是由于C#的运行机制造成的,原因如下:

新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类。构造函数的执行则相反,先执行父类的,再执行本身的。

如果类包含对父类虚函数的重载,在父类构造函数中调用虚函数时,会执行函数表中继承类的虚函数,这就有问题了。

下面是个测试例子:

public class Base
{
public Base()
{
System.Console.WriteLine("Base.Base");
ABitDangerousCall();
} public virtual void ABitDangerousCall()
{
System.Console.WriteLine("Base.ABitDangerousCall");
} private class Inner
{
public Inner()
{
System.Console.WriteLine("Base.Inner.Inner");
}
}
private Inner inner = new Inner();
} class Derived : Base
{
public Derived()
{
System.Console.WriteLine("Derived.Derived");
ctorInitializedMember = ;
} // ctorInitializedMember is default initialized to zero before the constructor initializes it.
private int ctorInitializedMember;
private int derivedInt = ; public override void ABitDangerousCall()
{
System.Console.WriteLine(String.Format("Derived.ABitDangerousCallctorInitializedMember={0} derivedInt={1}", ctorInitializedMember, derivedInt));
} private class Inner
{
public Inner()
{
System.Console.WriteLine("Derived.Inner.Inner");
}
}
private Inner inner = new Inner();
} class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
Console.Read();
}
}

如果真有在构造函数中调用虚函数的必要,应将该类或该重载的虚函数设为seal,以避免被继承。

关于在C#中构造函数中调用虚函数的问题的更多相关文章

  1. C++中构造函数能调用虚函数吗?(答案是语法可以,输出错误),但Java里居然可以

    环境:XPSP3 VS2005 今天黑总给应聘者出了一个在C++的构造函数中调用虚函数的问题,具体的题目要比标题复杂,大体情况可以看如下的代码: class Base { public: Base() ...

  2. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  3. C++ Daily 《3》----构造函数可否是虚函数

    C++ 中构造函数可否是虚函数? 绝不要!! 而且,在构造函数中调用虚函数也是不提倡的行为,因为会引发预想不到的结果. 因为,在 derived class 对象构造的过程中,首先调用的是基类的构造函 ...

  4. C++构造函数中不能调用虚函数

    在构造函数中调用虚函数,并不会产生多态的效果,就跟普通函数一样. c++ primer 第四版中497页15.4.5构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...

  5. C++ 构造函数中调用虚函数

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...

  6. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  7. 在构造函数和析构函数中调用虚函数------新标准c++程序设计

    在构造函数和析构函数中调用虚函数不是多态,因为编译时即可确定调用的是哪个函数.如果本类有该函数,调用的就是本类的函数:如果本类没有,调用的就是直接基类的函数:如果基类没有,调用的就是间接基类的函数,以 ...

  8. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  9. C++中为什么构造函数不能是虚函数,析构函数是虚函数

    一, 什么是虚函数? 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语 ...

随机推荐

  1. oracle学习不错的网站

    http://oracle-base.com/articles/linux/rlwrap.php

  2. mysql 得到重复的记录

    select devicetoken from client_user group by devicetoken having count(devicetoken)>1

  3. http协议之request

    一.请求的基本格式 请求的基本格式包括请求行,请求头,请求实体三部分.例如:GET /img/bd_logo1.png HTTP/1.1Accept: */*Referer: http://www.b ...

  4. React Native实例

    本文主要包括以下内容 View组件的实例 Text组件实例 Navigator组件实例 TextInput组件实例 View组件的实例 效果如下 代码如下 /** * Sample React Nat ...

  5. HTML5学习之画布和SVG(四)

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  6. 【翻译十九】-java之执行器

    Executors In all of the previous examples, there's a close connection between the task being done by ...

  7. MySQL基础二

    视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( SEL ...

  8. 解决oracle11g 空表不能exp导出的问题

    在使用exp备份数据库,然后使用imp导入的时候出现了好多表或者视图不存在的错误信息. 究其原因,是11G中增加了一个新的特性:数据条数是0时不分配segment,所以就不能被导出. 解决思路:就是向 ...

  9. SVN-简要说明

    SVN官方推荐在一个版本库的根目录下先建立trunk.branches.tags这三个文件夹,其中trunk是开发主干,存放日常开发的内容:branches存放各分支的内容,比如为不同客户定制的不同版 ...

  10. [Spring] 事务级别定义

    记录下来,以后备用 //事务传播属性 @Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个 @Transac ...