如果在一個類中定義了虛屬性或者虛方法,又在構造函數中訪問了這個虛屬性或方法,那麼很可能會埋下一個安全隱患。 ...
如果在一個類中定義了虛屬性或者虛方法,又在構造函數中訪問了這個虛屬性或方法,此時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方法在子類構造函數第一步調用,子類在繼承這個方法時初始化需要的依賴。