c# - 静态只读字段初始化程序与静态构造函数初始化

标签 c# c#-3.0 c#-2.0 initializer static-constructor

以下是初始化静态只读字段的两种不同方式。这两种方法有区别吗?如果是,什么时候应该优先选择一个?

class A
{
    private static readonly string connectionString =
        WebConfigurationManager.ConnectionStrings["SomeConnection"].ConnectionString;
}

class B
{
    private static readonly string connectionString;

    static B()
    {
        connectionString =
            WebConfigurationManager.ConnectionStrings["SomeConnection"].ConnectionString;
    }
}

最佳答案

这两者之间有一个细微的差别,可以在 IL 代码中看出 - 放置一个显式静态构造函数告诉 C# 编译器不要将类型标记为 beforefieldinit。 . beforefieldinit 会影响类型初始化程序何时运行,知道这一点在编写 lazy singletons in C# 时很有用。 ,例如。

简而言之,区别在于:

.class private auto ansi beforefieldinit A
.class private auto ansi B

在所有其他方面,它们都是相同的。反射器的输出:

A 类:

.class private auto ansi beforefieldinit A
    extends [mscorlib]System.Object
{
    .method private hidebysig specialname rtspecialname static void .cctor() cil managed
    {
        .maxstack 8
        L_0000: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
        L_0005: ldstr "SomeConnection"
        L_000a: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
        L_000f: ldfld string Connection::ConnectionString
        L_0014: stsfld string A::connectionString
        L_0019: ret 
    }

    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: ret 
    }

    .field private static initonly string connectionString
} 

B 类:

.class private auto ansi B
    extends [mscorlib]System.Object
{
    .method private hidebysig specialname rtspecialname static void .cctor() cil managed
    {
        .maxstack 8
        L_0000: nop 
        L_0001: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
        L_0006: ldstr "SomeConnection"
        L_000b: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
        L_0010: ldfld string Connection::ConnectionString
        L_0015: stsfld string B::connectionString
        L_001a: ret 
}

    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: ret 
    }


    .field private static initonly string connectionString    
}

关于c# - 静态只读字段初始化程序与静态构造函数初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2761393/

相关文章:

c# - 使 Directory.GetFiles() 忽略 protected 文件夹

c# - 您在 C# 中制作或看到过哪些非常有值(value)的流畅接口(interface)?他们有什么了不起?

c# - C# 3.0+ 中属性和字段的区别

asp.net - 使用 SVN uri 路径在没有工作副本的情况下在 SVN 中提交文件

c# - 编写此代码的更好方法而不是 2x foreach?

c# - 将数据保存在 Form2 中,帐户 ID 位于 1 列中,以查看谁拥有该数据

c# - NLog:如何控制 LogEventInfo 对象的消息格式?

c# - ASP :ListBox Get Selected Items - One Liner?

c# - 如何将C# datetimeOffset 转换为指定格式

c# - 如何设置一个程序来改变 C# 中的数量?