如果在一個類中定義了虛屬性或者虛方法,又在建構函式中訪問了這個虛屬性或方法,此時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
時出現了Null 參考報錯,因為基類建構函式先於子類建構函式運行,而子類建構函式中初始化了一個成員類,但是基類建構函式訪問虛成員時子類還沒構造,所以出現了Null 參考報錯。有多種方式可以避免這一情況,可以通過子類欄位初始化的方式來構造成員類,這個文法糖可避免建構函式的時序問題,第二個是可定義一個虛的Initialize方法在子類建構函式第一步調用,子類在繼承這個方法時初始化需要的依賴。