静态只读字段初始VS静态构造函数初始化 [英] static readonly field initializer vs static constructor initialization

查看:263
本文介绍了静态只读字段初始VS静态构造函数初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是两种不同的方法来初始化静态只读域。有两种方法之间的差异?如果是的话,应该何时之一pferred比其他$ P $?

  A级
{
    私人静态只读字符串的connectionString = WebConfigurationManager.ConnectionStrings [SomeConnection]的ConnectionString。
}B类
{
    私人静态只读字符串的connectionString;    静态B()
    {
        的connectionString = WebConfigurationManager.ConnectionStrings [SomeConnection]的ConnectionString。
    }
}


解决方案

有这两个,它可以在IL code可以看出之间有一个微妙的不同 - 把一个明确的静态构造函数告诉C#编译器不标记其类型为 beforefieldinit 。当类型初始化运行并了解这是有用的,当写懒单身的beforefieldinit影响一>,例如

在短暂的区别是这样的:

 的.class民营汽车ANSI beforefieldinit一个
的.class私人汽车ANSI B

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

A类:

 的.class民营汽车ANSI beforefieldinit一个
    扩展[mscorlib程序] System.Object的
{
    。方法私人hidebysig specialname rtspecialname静态无效.cctor()CIL管理
    {
        .maxstack 8
        L_0000:ldsfld类[mscorlib程序] System.Collections.Generic.Dictionary`2<字符串,类连接> WebConfigurationManager ::的ConnectionStrings
        L_0005:ldstrSomeConnection
        !L_000a:callvirt实例1 [mscorlib程序] System.Collections.Generic.Dictionary`2<字符串,类连接> :: get_Item(!0)
        L_000f:ldfld字符串连接::的ConnectionString
        L_0014:stsfld字符串A ::的connectionString
        L_0019:RET
    }    市民。方法hidebysig specialname rtspecialname实例无效.ctor()CIL管理
    {
        .maxstack 8
        L_0000:ldarg.0
        L_0001:呼叫实例无效[mscorlib程序] System.Object的构造函数::()。
        L_0006:RET
    }    技术领域私有静态initonly字符串的connectionString
}

B类:

 的.class民营汽车ANSI B
    扩展[mscorlib程序] System.Object的
{
    。方法私人hidebysig specialname rtspecialname静态无效.cctor()CIL管理
    {
        .maxstack 8
        L_0000:NOP
        L_0001:ldsfld类[mscorlib程序] System.Collections.Generic.Dictionary`2<字符串,类连接> WebConfigurationManager ::的ConnectionStrings
        L_0006:ldstrSomeConnection
        !L_000b:callvirt实例1 [mscorlib程序] System.Collections.Generic.Dictionary`2<字符串,类连接> :: get_Item(!0)
        L_0010:ldfld字符串连接::的ConnectionString
        L_0015:stsfld字符串B ::的connectionString
        L_001a:RET
}    市民。方法hidebysig specialname rtspecialname实例无效.ctor()CIL管理
    {
        .maxstack 8
        L_0000:ldarg.0
        L_0001:呼叫实例无效[mscorlib程序] System.Object的构造函数::()。
        L_0006:RET
    }
    技术领域私有静态initonly字符串的connectionString
}

Below are two different ways to initialize static readonly fields. Is there a difference between the two approaches? If yes, when should one be preferred over the other?

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

There is one subtle difference between these two, which can be seen in the IL code - putting an explicit static constructor tells the C# compiler not to mark the type as beforefieldinit. The beforefieldinit affects when the type initializer is run and knowing about this is useful when writing lazy singletons in C#, for example.

In brief the difference is this:

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

In all other aspects they are the same. Output from Reflector:

Class 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
} 

Class 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    
}

这篇关于静态只读字段初始VS静态构造函数初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆