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构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...
随机推荐
- Spring学习(七)——增强类
Spring 切点 什么是切点?切点(Pointcut),每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物.但在这为数从多的连接点中,如何定位 ...
- ngx_http_rewrite_module(重定向)
1:指定rewrite规则 rewrite regex replacement [flag]; 什么是rewrite规则:If the specified regular expression m ...
- 软工网络15团队作业4-DAY8
每日例会 昨天的工作. 张陈东芳:可导入部分类信息,继续尝试将所有信息导入: 吴敏烽:商品类的规范化编写: 周汉麟:界面的排版继续优化: 林振斌:按照浏览历史,次数等,继续优化商品类排序: 李智:研究 ...
- 【Leetcode】 328. Odd Even Linked List
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...
- 微信获取 openid 静默及非静默
<?php /* 需要的微信公众号配置信息 APPID : 绑定支付的APPID APPSECRET : 公众帐号secert */ class Index { // 配置账号信息 privat ...
- 如何在DBGrid里实现Shift+“选择行”区间多选的功能!
DELPHI 的TDBGrid 控 件 主 要 用 来 处 理 数 据 表, 它 的 属 性 中 有 一 个dgMultiSelect, 若 此 属 性 设 定 为TRUE, 则 可 以 选 中 多 ...
- Android定位测试(深坑)
问题:我们是一个海外app,市场部去马来西亚打开那边的市场,发现了一个问题,就是我们的app定位有问题,还是成都的定位,主要原因是在马来西亚使用这个app,请求中带的经纬度参数是成都的,导致服务器返回 ...
- RGB555转RGB565
做tft彩屏显示图片的时候,显示16位位图,显示屏的显示模式为RGB565.使用img2lcd转换后的16位bmp,显示出来后,颜色有偏差:转换为565格式的bin文件,显示完全正常,可以确定转换为b ...
- Angel Beats,AFOer Beats?
意识模糊的时候适合写一些奇怪的东西? NOI退役之后我尝试了很多方法调节心态.(比如做OI题,出OI题,学文化课,读书,吃饭,睡觉,水群,看番,推galgame). 然而看啥都是退役的画风.比如说推W ...
- 【JavaScript】时间戳转日期格式
时间戳: 1480570979000 $.ajax({ url : "getOrderMsg?shiplabel="+ shiplabel, type : "get&qu ...