在知乎上看到一个关于“泛基“的实现,感觉挺有意思,想试试效果,代码如下:
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(); } }
先忽略这段代码的作用,重点是运行后控制台没有任何输出。跟踪一下发现根本没有走MyClass(),DataForThisType的值一直是null。关于静态构造方法,网上的解释是:
这就有问题了,MyClass的静态构造方法不仅没被优先调用,甚至全程都没有被调用。难道上述这个说法是错的?为了排除干扰,给上述代码简化一下
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"; } }
运行结果还是一样,没有输出,TestChild的静态构造没被执行。回头再来看静态构造方法的调用条件:在创建第一个实例或者静态成员被引用时!!!实例是肯定没有的,但
是我有引用静态成员啊..等等,我引用的好像是父类的静态成员,难道父类的静态成员不行?说好的继承全部家产呢?那就再来试试,给TestChild声明一个自己的静态属性。
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"; } }
输出如下:
目前为止可以得出两个结论:
1)想触发一个类的静态构造方法?要么实例化它,要么访问它的静态成员,访问它基类的的静态成员是不行的。
2)静态成员的继承其实并不是真正的继承,或者说根本就无法继承,只是访问父类的静态成员而已。但与实例成员不同的是,用protected修饰的静态成员
可以在其派生类中访问,但用protected修饰的非静态成员,则不可访问。下面代码体会一下,new TestBase().hh =" ";这句报错。
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 = ""; } }
以上、欢迎交流指正。如有侵权,请联系作者删除。
如对本文有疑问, 点击进行留言回复!!
Java面向对象中:方法重载和方法重写以及区别、 this关键字和super关键字以及区别
【开源】使用Angular9和TypeScript开发RPG游戏(补充了Buffer技能)
网友评论