class Program
{
static void Main(string[] args)
{
Foo.Calc("Foo");
}
}
public abstract class Base
{
protected static Func<string, int> CalcFunction;
public static void Calc(string str)
{
Console.WriteLine(CalcFunction(str));
}
}
public class Foo : Base
{
static Foo()
{
CalcFunction = s => { return s.Length; };
}
}
当我试图调用Foo.Calc(“Foo”)时;我有异常“对象引用没有设置为对象的实例。” 因为没有调用Foo的静态构造函数而CalcFunction为null。我不想在Foo类中使用Init方法,并在调用Calc()之前调用它。
我可以更改调用构造函数的顺序吗?
答案 0 :(得分:6)
不 - 您的代码已编译为
Base.Calc("Foo");
...所以Foo
根本没有被初始化。
这不是运行静态构造函数的 order 的问题......而Foo
的静态构造函数根本就没有运行。
基本上,你应该改变你的设计。您可以强制Foo
的静态构造函数通过创建Foo
的实例来运行,但这非常讨厌...您的代码最终不会被清楚那样。
答案 1 :(得分:2)
C#保证在使用Base
中的任何代码之前,运行Base
的静态构造函数。没有什么可以保证Foo
中的任何代码都能运行。 (您已拨打Foo.Calc
的电话,但这实际上是对Base.Calc
的调用。)
没有简单的解决方法:您可以引入显式初始化方法,或者展平类层次结构,或将CalcFunction
移动到Foo
。
答案 2 :(得分:1)
您似乎误解了静态和抽象关键字的使用。拥有一个只有静态成员的抽象类几乎没有任何意义。你确定这不是你想要的更接近:
class Program
{
static void Main(string[] args)
{
var foo = new Foo()
foo.Calc("Foo");
}
}
public abstract class Base
{
protected Func<string, int> CalcFunction;
public void Calc(string str)
{
Console.WriteLine(CalcFunction(str));
}
}
public class Foo : Base
{
public Foo()
{
this.CalcFunction = s => { return s.Length; };
}
}