C# 调用构造函数的顺序 类程序 { 静态void Main(字符串[]参数) { Foo.Calc(“Foo”); } } 公共抽象类基 { 受保护的静态功能计算功能; 公共静态无效计算(字符串str) { Console.WriteLine(CalcFunction(str)); } } 公共类Foo:Base { 静态Foo() { CalcFunction=s=>{返回s.Length;}; } }

C# 调用构造函数的顺序 类程序 { 静态void Main(字符串[]参数) { Foo.Calc(“Foo”); } } 公共抽象类基 { 受保护的静态功能计算功能; 公共静态无效计算(字符串str) { Console.WriteLine(CalcFunction(str)); } } 公共类Foo:Base { 静态Foo() { CalcFunction=s=>{返回s.Length;}; } },c#,C#,当我试图调用Foo.Calc(“Foo”);我有一个异常“对象引用未设置为对象的实例” 因为没有调用Foo的静态构造函数,并且CalcFunction为null。我不想对Foo类使用Init方法并在调用Calc()之前调用它 我可以更改调用构造函数的顺序吗?否-您的代码已编译成 class Program { static void Main(string[] args) { Foo.Calc("Foo"); } } public abstract

当我试图调用Foo.Calc(“Foo”);我有一个异常“对象引用未设置为对象的实例” 因为没有调用Foo的静态构造函数,并且CalcFunction为null。我不想对Foo类使用Init方法并在调用Calc()之前调用它


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

否-您的代码已编译成

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
根本没有被初始化

这不是运行静态构造函数的顺序问题。。。这是因为
Foo
的静态构造函数根本没有运行

基本上,你应该改变你的设计。您可以通过创建
Foo
的实例来强制运行
Foo
的静态构造函数,但这非常糟糕。。。您的代码不会以这种方式结束。

C#保证在使用
Base
中的任何代码之前,运行
Base
的静态构造函数。无法保证
Foo
中的任何代码都会运行。(您已经编写了对
Foo.Calc
的调用,但这实际上是对
Base.Calc
的调用)


没有简单的解决方法:您可以引入显式init方法,或者将类层次结构扁平化,或者将
CalcFunction
移动到
Foo

,似乎您误解了静态和抽象关键字的使用。拥有一个只有静态成员的抽象类几乎毫无意义。您确定这与您所尝试的不太接近:

Base.Calc("Foo");
类程序
{
静态void Main(字符串[]参数)
{
var foo=new foo()
foo.Calc(“foo”);
}   
}
公共抽象类基
{
受保护的函数CalcFunction;
公共无效计算(字符串str)
{
Console.WriteLine(CalcFunction(str));
}
}
公共类Foo:Base
{
公共食物(
{
this.CalcFunction=s=>{返回s.Length;};
}
}

混合继承和静态成员似乎有些奇怪。如果
Calc
CalcFunction
不是静态的,那么
Foo
将有一个常规实例构造函数,并且
CalcFunction
将在调用
Calc
之前进行初始化。更好的做法是:将
CalcFunction
设为私有,并添加一个构造函数:
protectedbase(Func-CalcFunction)
你能解释一下为什么Foo.Calc(“Foo”);将被编译成Base.Calc(“Foo”)?@乌克兰:因为实际上没有像
Foo.Calc
这样的成员。编译器允许将
Base.Calc
引用为
Foo.Calc
,但您真正引用的成员是
Base.Calc
,因此发出的代码就是这样包含的。
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; };
    }
}