C#为何不推荐在构造函数中访问虚成员

如果在一个类中定义了虚属性或者虚方法,又在构造函数中访问了这个虚属性或方法,此时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#为何不推荐在构造函数中访问虚成员的更多相关文章
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- C++ 构造函数中调用虚函数
我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...
- C# 构造函数中调用虚方法的问题
请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...
- C#中访问私有成员
首先访问一个类的私有成员不是什么好做法.大家都知道私有成员在外部是不能被访问的.一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员造访,可以套用下面这种非常好的方式去解决. pr ...
- C#中访问私有成员技巧
源代码是别人的,你就不能修改源代码,只提供给你dll.或者你去维护别人的代码,源代码却有丢失.这样的情况如果你想知道私有成员的值,甚至去想直接调用类里面的私有方法.那怎么办呢?其实在.net中访问私有 ...
- 避免在构造函数中调用虚方法(Do not call overridable methods in constructors)
CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现.但在这个时候,尚未完成对继承层次结构中所有字段的初始化.所以,调用虚方法会导致不可预测的 ...
- C#中访问私有成员--反射
首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...
- 编写高质量代码改善C#程序的157个建议——建议95:避免在构造方法中调用虚成员
建议95:避免在构造方法中调用虚成员 在构造方法中调用虚方法会带来一些意想不到的错误,虽然这种方法不常见,但还是需要注意这类陷阱. static void Main() { American amer ...
- C++构造函数中不能调用虚函数
在构造函数中调用虚函数,并不会产生多态的效果,就跟普通函数一样. c++ primer 第四版中497页15.4.5构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...
随机推荐
- Codeforces Beta Round #14 (Div. 2) D. Two Paths 树的直径
题目链接: http://codeforces.com/contest/14/problem/D D. Two Paths time limit per test2 secondsmemory lim ...
- 转 下一代云计算模式:Docker正掀起个性化商业革命
下一代云计算模式:Docker正掀起个性化商业革命 作者: 吴宁川 来源: ITValue 发布时间: 2015-09-20 10:41 阅读: 14052 次 推荐: 26 原文链接 ...
- String、Date、Calendar之间的转换
1.String.Date.Calendar之间的转换 要用到格式化类SimpleDateFormat package com.rong.se; import java.text.ParseExcep ...
- 软工网络15团队作业4-DAY7
每日例会 昨天的工作. 张陈东芳:sql连接的基本完成,尝试被其他类调用,未导入全部商品信息: 吴敏烽:基本完成商品信息的调用: 周汉麟:设定商品的调用规则: 林振斌:设计缓存区代码,用于存取最近浏览 ...
- 软工网络15团队作业4-DAY4
每日立会 昨天的工作. 张陈东芳:sql语句存储商品信息 吴敏烽:调试获取商品信息的方法 周汉麟:根据商品编号来获取商品资料方法调试 林振斌:输出最近浏览记录的方法检查 李智:cookies的检查 全 ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺-5
一.当天站立式会议照片: 二.项目进展 昨天已完成的工作: 日期等细致信息的处理,对添加账单日期化. 明天计划完成的工作: 完成对账单的编辑,删除等操作,以及开始服务器的编写工作 工作中遇到的困难: ...
- Mware中CentOS设置静态IP
Mware中CentOS设置静态IP 因为之前搭建的MongoDB分片没有采用副本集,最近现网压力较大,所以准备研究一下,于是在自己电脑的虚拟机中搭建环境,但是发现之前VMware设置的是DHCP ...
- Hadoop RPC protocol description--转
原文地址:https://spotify.github.io/snakebite/hadoop_rpc.html Snakebite currently implements the followin ...
- BZOJ3884 上帝与集合的正确用法(欧拉函数)
设f(n)为模n时的答案,由2k mod n=2k mod φ(n)+φ(n) mod n(并不会证),且k mod φ(n)=f(φ(n)),直接就可以得到一个递推式子.记搜一发即可. #inclu ...
- Day22-1-知识回顾
1. 知识点概要 --Session --CSRF --Model操作 --Form验证(ModelForm) --中间件 --缓存 2.知识回顾 2.1客户端请求及服务器端返回,都包含请求头和bod ...