一上代碼,后解釋
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestStatic { class Program { static void Main(string[] args) { Console.WriteLine("解決字段初始化無法引用非靜態字段問題"); A a = new A(new B()); Console.WriteLine(a.restrs); //利用屬性調用就可以解決 } } public class A { public A(B obj) { this.str = obj; Console.WriteLine(str.Say2()); //利用構造函數也可以解決 } public B str { get; set; } //string a = str.Say2(); //字段初始化無法引用非靜態字段 //public string restrs = restr(); //字段初始化無法引用非靜態字段 //而通過屬性調用就可以編譯通過 public string restrs { get { return restr(); } set { restrs = value; } } public string restr() { return "1》利用屬性調用就可以解決"; } } public class B { public B() { } public string Say2() { return "2》利用構造函數也可以解決"; } } }
二,字段初始化無法引用非靜態字段,原因:
1》C#語法規則:在 C# 中不允許使用未初始化的變量。
2》屬性內存和變量內存的分配的時間不一樣。 屬性是用的時候分配,而變量是在類初始化時候分配。
3》在實例一個類時,因為靜態字段賦值動作已經在靜態構造函數中完成,實例化的字段會在非靜態構造函數中實例化,而兩者的時間前后是靜態構造函數執行早於非靜態構造函數,也洽洽是這個原因會造成兩個問題:
1,當你用非靜態字段給靜態字段賦值時,字段一直為空錯誤
2,當你在類中給非靜態賦值時:字段初始化無法引用非靜態字段
三,解決方法:
1》因為初始化的時候順序問題造成的問題,我們可以將對應代碼放到當前需要賦值的類的構造函數中執行。
2》使用屬性的get來賦值,如上例子