[转] [翻译]C# Object Initialization[完整版]
[翻譯]C# Object Initialization[完整版]
原文地址:http://www.csharp411.com/c-object-initialization/
譯者:star65225692
當(dāng)構(gòu)造一個C#對象時,理解對象的作用域和構(gòu)造器被初始化的序列是很重要的
示例
下面的是一個C#控制臺程序的例子,這個例子演示了對象初始化的次序這個程序創(chuàng)建基對象的派生對象,包含了靜態(tài)化和實例化構(gòu)造器以及作用域,兩個作用域"Field1"和"Field2"在他們的定義里被初始化,然而 "Field3"在構(gòu)造器里被初始化.同時也包含了一個證明為什么不能從構(gòu)造器里調(diào)用虛方法的虛方法.當(dāng)每個作用域和構(gòu)造器被初始化時就會寫入控制臺,因此你可以看到初始化的序列
using System;
namespace ObjectInit
{
class Program
{
static void Main( string[] args )
{
??????????? Derived d = new Derived();
??????????? Console.ReadLine();
??????? }
??? }
class Base
{
public Base()
{
??????????? Console.WriteLine( "Base.Instance.Constructor" );
this.m_Field3 = new Tracker( "Base.Instance.Field3″ );
this.Virtual();
??????? }
static Base()
{
??????????? Console.WriteLine( "Base.Static.Constructor" );
??????? }
private Tracker m_Field1 = new Tracker( "Base.Instance.Field1″ );
private Tracker m_Field2 = new Tracker( "Base.Instance.Field2″ );
private Tracker m_Field3;
static private Tracker s_Field1 = new Tracker( "Base.Static.Field1″ );
static private Tracker s_Field2 = new Tracker( "Base.Static.Field2″ );
virtual public void Virtual()
{
??????????? Console.WriteLine( "Base.Instance.Virtual" );
??????? }
??? }
class Derived : Base
{
public Derived()
{
??????????? Console.WriteLine( "Derived.Instance.Constructor" );
this.m_Field3 = new Tracker( "Derived.Instance.Field3″ );
??????? }
static Derived()
{
??????????? Console.WriteLine( "Derived.Static.Constructor" );
??????? }
private Tracker m_Field1 = new Tracker( "Derived.Instance.Field1″ );
private Tracker m_Field2 = new Tracker( "Derived.Instance.Field2″ );
private Tracker m_Field3;
static private Tracker s_Field1 = new Tracker( "Derived.Static.Field1″ );
static private Tracker s_Field2 = new Tracker( "Derived.Static.Field2″ );
override public void Virtual()
{
??????????? Console.WriteLine( "Derived.Instance.Virtual" );
??????? }
??? }
class Tracker
{
public Tracker( string text )
{
??????????? Console.WriteLine( text );
??????? }
??? }
}
下面就是來自這個示例程序的控制臺輸出
Derived.Static.Field1Derived.Static.Field2
Derived.Static.Constructor
Derived.Instance.Field1
Derived.Instance.Field2
Base.Static.Field1
Base.Static.Field2
Base.Static.Constructor
Base.Instance.Field1
Base.Instance.Field2
Base.Instance.Constructor
Base.Instance.Field3
Derived.Instance.Virtual
Derived.Instance.Constructor
Derived.Instance.Field32個階段的構(gòu)建
注意在C#對象初始化的問題中還有個潛在的圈套。當(dāng)初始化以派生對象開始轉(zhuǎn)到基類對象時,構(gòu)造函數(shù)以相反次序進(jìn)行初始化,先執(zhí)行基類構(gòu)造函數(shù),再執(zhí)行派生函數(shù)。
??????? 當(dāng)你試圖通過基構(gòu)造函數(shù)調(diào)用一個虛方法時,上述情況就會發(fā)生。因為派生構(gòu)造函數(shù)還未被執(zhí)行,所以當(dāng)虛方法通過基類函數(shù)執(zhí)行時,派生對象或許就不會完全初始化。
??????? 正如在案例程序顯示的那樣,當(dāng)基構(gòu)造函數(shù)調(diào)用虛方法時(程序輸出顯示:Derived.Instance.Virtual),由于派生構(gòu)造函數(shù)未被執(zhí)行,派生對象的Field3并未被初始化。如果虛方法是建立在一個需要被初始化的Field3,此時程序?qū)⒊鲥e。
??????? 因此,你不能在對象函數(shù)中使用虛方法。而是在你第一次構(gòu)建對象處執(zhí)行“2個階段的構(gòu)建”,此時再使用虛方法,如下:
Derived d = new Derived();
??????? d.Virtual();
C#對象初始化提示:
一些關(guān)于C#對象初始化的一般規(guī)則和提示:
先變量后構(gòu)造函數(shù).變量先被初始化,然后構(gòu)造函數(shù)被執(zhí)行
先靜態(tài)化后實例化.當(dāng)一個類被訪問時,靜態(tài)變量和構(gòu)造函數(shù)最先被初始化.接著是對象的實例化變量和構(gòu)造函數(shù)被初始化
先派生類后基類.對于變量和靜態(tài)構(gòu)造函數(shù),派生對象在基對象之前被初始化.比如C類派生自B類,B類派生自A類,那么變量和靜態(tài)構(gòu)造函數(shù)被初始化次序是C-B-A.
除了實例構(gòu)造函數(shù). 對于實例構(gòu)造函數(shù),基類構(gòu)造函數(shù)在派生類構(gòu)造函數(shù)之前執(zhí)行,實例構(gòu)造函數(shù)被執(zhí)行次序是A-B-C.
不要假定變量的次序.Fields依據(jù)它們在源文件中的聲明的順序依次初始化.然而,自從程序員和工具可以隨意安排變量的聲明后,你不應(yīng)該在依靠變量任何特別的次序初始化
對虛方法用兩個階段的構(gòu)建.避免從一個構(gòu)造器調(diào)用虛方法. 如果在初始化一個對象時需要調(diào)用一些虛方法,應(yīng)在完整構(gòu)造該對象的地方使用兩階段的構(gòu)建,并隨后調(diào)用已構(gòu)造對象的初始化方法。
轉(zhuǎn)載于:https://www.cnblogs.com/QLeelulu/archive/2008/03/26/1123790.html
總結(jié)
以上是生活随笔為你收集整理的[转] [翻译]C# Object Initialization[完整版]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式1实践-开篇
- 下一篇: [zz]正则表达式使用详解