调用构造函数的顺序

时间:2010-12-14 09:58:13

标签: c#

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()之前调用它。

我可以更改调用构造函数的顺序吗?

3 个答案:

答案 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; };
    }
}