我有一个类定义为:
public class DatabaseEntity<T> where T : DatabaseEntity<T> {
public static string Query { get; protected set; }
public static IList<T> Load() {
return Database.Get(Query);
}
}
public class Node : DatabaseEntity<Node> {
static Node() {
Node.Query = @"SELECT Id FROM Node";
}
}
当我从代码隐藏 (Window.xaml.cs
) 运行 Node.Load()
时,Node 的静态构造函数从不触发;或者至少没有遇到断点,也没有将 Node.Query 设置为 null 以外的任何值。
为什么会发生这种情况?
解决方案
查看下面的答案以获得一些解决方案。对于我的情况,我决定简单地公开 Query
变量,并将 Query
的所有实例设置在一个地方。 (不理想,但它有效。)
最佳答案
问题在于您对何时调用静态构造函数的假设。 documentation ,这不是最清楚的,指出
It is called automatically before the first instance is created or any static members are referenced.
你可以假设如果你调用
Node.Load();
您正在 Node
类上调用静态方法,但实际上您是在基类上调用它,因为它是在基类上实现的。
因此,要解决此问题,您有两种选择。首先,您可以通过在调用 Load()
var foo = new Node(); // static ctor triggered
Node.Load();
或者创建一个 protected 虚拟成员,基类可以调用它来获取查询值(不幸的是,这里不能使用抽象)
public class DatabaseEntity<T> where T : Derp {
protected abstract string Query { get; }
public static IList<T> Load() {
return Database.Get(new DatabaseEntity<T>().Query);
}
}
这两个都是hacky。最好完全放弃静态并使用实例方法。静态应该谨慎使用,因为它们会导致紧密耦合和其他设计问题,例如这个。
关于c# - 访问基本成员时未调用子静态构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27487285/