C#:继承过程中的静态成员
在知乎上看到一個(gè)關(guān)于“泛基“的實(shí)現(xiàn),感覺(jué)挺有意思,想試試效果,代碼如下:
public abstract class MyBase<T> where T : MyBase<T>{public static string DataForThisType { get; set; }public static T Instance { get; protected set; }public static readonly IReadOnlyDictionary<string, MemberInfo> Members = typeof(T).GetMembers().ToDictionary(x => x.Name);}public class MyClass : MyBase<MyClass>{static MyClass(){DataForThisType = string.Format("MyClass got {0} members", Members.Count);Instance = new MyClass();}} class Program{static void Main(string[] args){Console.Write(MyClass.DataForThisType);Console.WriteLine();Console.ReadLine();}}先忽略這段代碼的作用,重點(diǎn)是運(yùn)行后控制臺(tái)沒(méi)有任何輸出。跟蹤一下發(fā)現(xiàn)根本沒(méi)有走M(jìn)yClass(),DataForThisType的值一直是null。關(guān)于靜態(tài)構(gòu)造方法,網(wǎng)上的解釋是:
- 通常情況下:最先調(diào)用基類的構(gòu)造方法,但如果該類有靜態(tài)構(gòu)造方法,且首次調(diào)用該類,則先調(diào)用該類的靜態(tài)構(gòu)造方法,再調(diào)用其基類的靜態(tài)構(gòu)造方法。
Child.Static->Super.Static->Super.Instance->Child Instance - 靜態(tài)構(gòu)造方法是.net調(diào)用的,在創(chuàng)建第一個(gè)實(shí)例或者靜態(tài)成員被引用時(shí),.net將自動(dòng)調(diào)用靜態(tài)構(gòu)造方法來(lái)初始化類。
- 通常情況下:最先調(diào)用基類的構(gòu)造方法,但如果該類有靜態(tài)構(gòu)造方法,且首次調(diào)用該類,則先調(diào)用該類的靜態(tài)構(gòu)造方法,再調(diào)用其基類的靜態(tài)構(gòu)造方法。
這就有問(wèn)題了,MyClass的靜態(tài)構(gòu)造方法不僅沒(méi)被優(yōu)先調(diào)用,甚至全程都沒(méi)有被調(diào)用。難道上述這個(gè)說(shuō)法是錯(cuò)的?為了排除干擾,給上述代碼簡(jiǎn)化一下
?
class Program{static void Main(string[] args){Console.Write(TestChild.StaticPropertyBase);Console.WriteLine();Console.ReadLine();}}public class TestBase{public static string StaticPropertyBase { get; protected set; }}public class TestChild : TestBase{static TestChild(){StaticPropertyBase = typeof(TestChild) + ":" + "StaticPropertyBase"; }}?
運(yùn)行結(jié)果還是一樣,沒(méi)有輸出,TestChild的靜態(tài)構(gòu)造沒(méi)被執(zhí)行。回頭再來(lái)看靜態(tài)構(gòu)造方法的調(diào)用條件:在創(chuàng)建第一個(gè)實(shí)例或者靜態(tài)成員被引用時(shí)!!!實(shí)例是肯定沒(méi)有的,但
是我有引用靜態(tài)成員啊..等等,我引用的好像是父類的靜態(tài)成員,難道父類的靜態(tài)成員不行?說(shuō)好的繼承全部家產(chǎn)呢?那就再來(lái)試試,給TestChild聲明一個(gè)自己的靜態(tài)屬性。
class Program{static void Main(string[] args){Console.Write(TestChild.StaticPropertyChild);Console.WriteLine();Console.Write(TestChild.StaticPropertyBase);Console.WriteLine();Console.Write(TestBase.StaticPropertyBase);Console.WriteLine();Console.ReadLine();}}public class TestBase{public static string StaticPropertyBase { get; protected set; }}public class TestChild : TestBase{public static string StaticPropertyChild { get; set; }static TestChild(){StaticPropertyBase = typeof(TestChild) + ":" + "StaticPropertyBase";StaticPropertyChild = "StaticPropertyChild"; }}輸出如下:
目前為止可以得出兩個(gè)結(jié)論:
1)想觸發(fā)一個(gè)類的靜態(tài)構(gòu)造方法?要么實(shí)例化它,要么訪問(wèn)它的靜態(tài)成員,訪問(wèn)它基類的的靜態(tài)成員是不行的。
2)靜態(tài)成員的繼承其實(shí)并不是真正的繼承,或者說(shuō)根本就無(wú)法繼承,只是訪問(wèn)父類的靜態(tài)成員而已。但與實(shí)例成員不同的是,用protected修飾的靜態(tài)成員
? ? ?可以在其派生類中訪問(wèn),用protected修飾的非靜態(tài)成員,則不可訪問(wèn)。下面代碼體會(huì)一下,new TestBase().hh =" ";這句報(bào)錯(cuò)。
? ? ?報(bào)錯(cuò)的原因描述有誤:實(shí)則是因?yàn)樵谝粋€(gè)實(shí)例中訪問(wèn)了另一個(gè)實(shí)例的protected成員,與是否是基類的實(shí)例無(wú)關(guān)
public class TestBase{public static string StaticPropertyBase { get; protected set; }public string hh { get; protected set; }}public class TestChild : TestBase{public static string StaticPropertyChild { get; set; }static TestChild(){StaticPropertyBase = typeof(TestChild) + ":" + "StaticPropertyBase";StaticPropertyChild = "StaticPropertyChild"; }TestChild(){hh = "";new TestBase().hh = "";}}以上、歡迎交流指正。如有侵權(quán),請(qǐng)聯(lián)系作者刪除。
?
轉(zhuǎn)載于:https://www.cnblogs.com/nevermore-wd/p/8569267.html
總結(jié)
以上是生活随笔為你收集整理的C#:继承过程中的静态成员的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java实现字母的大小写转换
- 下一篇: php中文分词nlp,几种常见的PHP中