如果我内联 HashSet 集合初始化,编译器是否知道只执行一次?

Fat*_*tie 3 c# collections static-initialization language-lawyer

我经常这样做...

private void Check()
 {
 string s = "blah";

 if ( new HashSet<string>{"Joe","Eddie","Buckethead"}.Contains(s) )
   Debug.Log("Guitarist.");
 }
Run Code Online (Sandbox Code Playgroud)

在管道中,HashSet实际上是否只创建一次(在启动时?编译时?)然后每次都使用?

顺便说一句,我假设如果你这样做:

private HashSet<string> g = new HashSet<string>()
                         {"Joe","Eddie","Buckethead"};
private void Check()
 {
 string s = "blah";

 if ( g.Contains(s) )
  Debug.Log("Guitarist.");
 }
Run Code Online (Sandbox Code Playgroud)

那么确实,当然它只在类实例化时完成一次。(或者,也许在编译时/启动时?但无论如何,只有一次。)

Eni*_*ity 5

这是第一个方法的 IL:

查看:
IL_0000:ldstr“废话”
IL_0005: stloc.0 // s
IL_0006:newobj System.Collections.Generic.HashSet..ctor
IL_000B:重复         
IL_000C:ldstr“乔”
IL_0011:调用virt System.Collections.Generic.HashSet.Add
IL_0016:流行音乐         
IL_0017:重复         
IL_0018:ldstr“艾迪”
IL_001D:调用virt System.Collections.Generic.HashSet.Add
IL_0022:流行音乐         
IL_0023:重复         
IL_0024:ldstr“桶头”
IL_0029:调用virt System.Collections.Generic.HashSet.Add
IL_002E:弹出         
IL_002F: ldloc.0 // s
IL_0030:callvirt System.Collections.Generic.HashSet.Contains
IL_0035:brfalse.s IL_0041
IL_0037:ldstr“吉他手。”
IL_003C:调用System.Console.WriteLine
IL_0041:返回         

这是第二种方法的代码:

查看:
IL_0000:ldstr“废话”
IL_0005: stloc.0 // s
IL_0006:ldarg.0     
IL_0007:ldfld g
IL_000C: ldloc.0 // s
IL_000D:callvirt System.Collections.Generic.HashSet.Contains
IL_0012: brfalse.s IL_001E
IL_0014:ldstr“吉他手。”
IL_0019:调用System.Console.WriteLine
IL_001E:返回         

这就是代码的优化编译。

所以,是的,第一个HashSet每次都会创建一个新的。

哦,我更改Debug.LogConsole.WriteLine,但这是一个微不足道的更改。