在 C# 中内联或在静态构造函数中初始化静态变量的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/218461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:36:05  来源:igfitidea点击:

Difference initializing static variable inline or in static constructor in C#

c#.netstaticconstructorinitialization

提问by Curro

I would like to know what is the difference between initializing a static member inline as in:

我想知道初始化静态成员内联有什么区别,如下所示:

class Foo
{
    private static Bar bar_ = new Bar();
}

or initializing it inside the static constructor as in:

或在静态构造函数中初始化它,如下所示:

class Foo
{
    static Foo()
    {
        bar_ = new Bar();
    }
    private static Bar bar_;
}

采纳答案by Jon Skeet

If you have a static constructor in your type, it alters type initialization due to the beforefieldinitflag no longer being applied.

如果您的类型中有静态构造函数,由于不再应用beforefieldinit标志,它会改变类型初始化。

It also affects initialization order - variable initializers are all executed before the static constructor.

它还影响初始化顺序 - 变量初始化器都在静态构造函数之前执行。

That's about it as far as I know though.

据我所知,仅此而已。

回答by Torbj?rn

In this case I don't believe there si any practical difference. If you need some logic in initializing the static variables - like if you would want to use different concrete types of an interface given different conditions - you would use the static constructor. Else, the inline initialization is fine in my book.

在这种情况下,我不相信有任何实际差异。如果您在初始化静态变量时需要一些逻辑——比如如果您想在给定不同条件的情况下使用不同的具体类型的接口——您将使用静态构造函数。否则,内联初始化在我的书中很好。

class Foo
{
    private static IBar _bar;

    static Foo()
    {
        if(something)
        {
            _bar = new BarA();
        }
        else
        {
            _bar = new BarB();
        }
    }
}

回答by Gishu

Twilight zone answer: There is a difference in order of executionbetween inline initializers and ctor assignment... when you mix in instance and static members and inheritance to boot.

Twilight zone 答案:内联初始值设定项和 ctor 分配之间的执行顺序存在差异……当您混合使用实例和静态成员以及继承来启动时。

For static members, static initializers 
Static ctors (execute bottom up)
Base static initializer
Base static ctor and so on

For instance members, initializers in current class execute first
Then initializers in base class execute ( up the chain)
Then top-most base ctor is executed (and we walk down now. Instance ctors execute top-down)
Finally current type's ctor is executed.

Example :)

例子 :)

public class CBase
    {
        static Talkative m_Baseob1 = new Talkative("Base Static Initializer-");
        static Talkative m_Baseob2;
        Talkative m_Baseob3 = new Talkative("Base Inst Initializer");
        Talkative m_Baseob4;
        static CBase()
        {
            Console.WriteLine("***MethodBegin: Static Base Ctor");
            m_Baseob2 = new Talkative("Base Static Ctor");
            Console.WriteLine("***MethodEnd: Static Base Ctor");
        }
        public CBase()
        {
            Console.WriteLine("***MethodBegin: Instance Base Ctor");
            m_Baseob4 = new Talkative("Base Instance Ctor");
            Console.WriteLine("***MethodEnd: Instance Base Ctor");
        }
    }
    public class CDerived : CBase
    {
        static Talkative m_ob1 = new Talkative("Derived Static Initializer");
        static Talkative m_ob2;
        Talkative m_ob3 = new Talkative("Derived Inst Initializer");
        Talkative m_ob4;
        static CDerived()
        {
            Console.WriteLine("***MethodBegin: Derived Static Ctor");
            m_ob2 = new Talkative("Derived Static Ctor");
            Console.WriteLine("***MethodEnd: Derived Static Ctor");
        }
        public CDerived()
        {
            Console.WriteLine("***MethodBegin: Derived Instance Ctor");
            m_ob4 = new Talkative("Derived Instance Ctor");
            Console.WriteLine("***MethodEnd: Derived Instance Ctor");
        }
    }
    internal class Talkative
    {
        public Talkative(string sID)
        {
            Console.WriteLine(sID + " - Talkative created" );
        }
    }

    # Main function somewhere
    CDerived s = new CDerived();

Output:

输出:

Derived Static Initializer - Talkative created

***MethodBegin: Derived Static Ctor
Derived Static Ctor - Talkative created
***MethodEnd: Derived Static Ctor

Derived Inst Initializer - Talkative created

Base Static Initializer- - Talkative created

***MethodBegin: Static Base Ctor
Base Static Ctor - Talkative created
***MethodEnd: Static Base Ctor

Base Inst Initializer - Talkative created

***MethodBegin: Instance Base Ctor
Base Instance Ctor - Talkative created
***MethodEnd: Instance Base Ctor

***MethodBegin: Derived Instance Ctor
Derived Instance Ctor - Talkative created
***MethodEnd: Derived Instance Ctor