静态只读字段初始VS静态构造函数初始化 [英] static readonly field initializer vs static constructor initialization
问题描述
下面是两种不同的方法来初始化静态只读域。有两种方法之间的差异?如果是的话,应该何时之一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屋!