如果在一个类中定义了虚属性或者虚方法,又在构造函数中访问了这个虚属性或方法,此时VisualStudio是不会给出警告,并且编译也没有问题,但是如果安装了Resharper插件则会给出警告提示:“在构造函数中访问了虚成员”,那么,这为何是一个安全隐患,下面给出一个例子说明:

using System;

namespace VirtualDemo
{
class Program
{
static void Main(string[] args)
{
var test = new SubClass();
Console.ReadKey();
}
} class BaseClass
{
protected virtual string VirtualProperty { get; set; } public BaseClass()
{
var p = VirtualProperty;
VirtualMethod();
} protected virtual void VirtualMethod()
{ }
} class SubClass : BaseClass
{
private MockClass _mockClass; public SubClass()
{
_mockClass = new MockClass();
} protected override string VirtualProperty
{
get { return _mockClass.MockProperty; }
set { _mockClass.MockProperty = value; }
} protected override void VirtualMethod()
{
var p = _mockClass.MockProperty;
}
} class MockClass
{
public string MockProperty { get; set; }
}
}

该示例很简单,在构造SubClass时出现了空引用报错,因为基类构造函数先于子类构造函数运行,而子类构造函数中初始化了一个成员类,但是基类构造函数访问虚成员时子类还没构造,所以出现了空引用报错。有多种方式可以避免这一情况,可以通过子类字段初始化的方式来构造成员类,这个语法糖可避免构造函数的时序问题,第二个是可定义一个虚的Initialize方法在子类构造函数第一步调用,子类在继承这个方法时初始化需要的依赖。

C#为何不推荐在构造函数中访问虚成员的更多相关文章

  1. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

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

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

  3. C# 构造函数中调用虚方法的问题

    请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...

  4. C#中访问私有成员

    首先访问一个类的私有成员不是什么好做法.大家都知道私有成员在外部是不能被访问的.一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员造访,可以套用下面这种非常好的方式去解决. pr ...

  5. C#中访问私有成员技巧

    源代码是别人的,你就不能修改源代码,只提供给你dll.或者你去维护别人的代码,源代码却有丢失.这样的情况如果你想知道私有成员的值,甚至去想直接调用类里面的私有方法.那怎么办呢?其实在.net中访问私有 ...

  6. 避免在构造函数中调用虚方法(Do not call overridable methods in constructors)

    CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现.但在这个时候,尚未完成对继承层次结构中所有字段的初始化.所以,调用虚方法会导致不可预测的 ...

  7. C#中访问私有成员--反射

    首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...

  8. 编写高质量代码改善C#程序的157个建议——建议95:避免在构造方法中调用虚成员

    建议95:避免在构造方法中调用虚成员 在构造方法中调用虚方法会带来一些意想不到的错误,虽然这种方法不常见,但还是需要注意这类陷阱. static void Main() { American amer ...

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

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

随机推荐

  1. Java 将数字转为16进制,然后转为字符串类型 将空格去掉。终结版

    //十进制转为十六进制 public class ArrayTest7 { public static void main(String[] args){ System.out.println(toH ...

  2. Sql server 中关闭ID自增字段(SQL取消ID自动增长)

    sql server在导入数据的时候,有时候要考虑id不变,就要先取消自动增长再导入数据,导完后恢复自增. 比如网站改版从旧数据库导入新数据库,数据库结构不相同,可能会使用insert into xx ...

  3. SQL 语句(增删改查)

    一.增:有4种方法1.使用insert插入单行数据: --语法:insert [into] <表名> [列名] values <列值> 例:insert into Strden ...

  4. 【第五周】alpha发布之小组评论

    对于昨天的阿尔法发布,有那么几点需要说一下: 1,对这次阿尔法发布的过程,我们组还是基本顺利的,由于之前吃过亏,这次我提前试用了一下投影仪,做了些调试,之后的发布过程起码设备上是正常的. 2,我们的项 ...

  5. 【week10】规格说明书练习-吉林市1日游

    假设我们全班同学及教师去吉林省吉林市1日游,请为这次活动给出规格说明书. 版本:1.0 编订:于淼 团队:2016级计算机技术全体同学 日期:2016/11/19 1.引言 1.1 编写目的 1.2 ...

  6. 程序员必看电影:Java 4-ever

    http://blog.csdn.net/zdwzzu2006/article/details/5863068

  7. 【.Net】输出的字符靠右对齐

    先看下面的这组字符,如果输出来,它是无法靠右对齐: " }; foreach (string s in s1) { string s2 = s; Console.WriteLine(s2); ...

  8. 题解 P1567 【统计天数】

    天哪!竟然没人用优先队列! 小金羊又来水题了... 优先队列中的大根堆帮助我们把时间复杂度降到O(n+logn) 首先我们先了解一下大根堆... 大根堆的性质:根节点比子节点大, 这意味着最上面的节点 ...

  9. Django新手图文教程-转发

    转发自:http://www.cnblogs.com/Leo_wl/p/5824541.html 一.Django简介 百度百科:开放源代码的Web应用框架,由Python语言编写...... 重点: ...

  10. jQuery多重事件绑定

    1. <a> a标签默认绑定了一个onclick事件,当自己再写一个onclick事件的时候,默认自己写的那个优先执行. 如下程序,先执行(123),然后再发生跳转. <!DOCTY ...