foreach Dictionary<>.Values or foreach Dictionary<>

后端 未结 4 1476
忘掉有多难
忘掉有多难 2021-01-07 06:54

I want to know the details of this two styles of iterating Dictionary collections in C#:

Dictionary xydic = new Dictionary

        
4条回答
  •  北海茫月
    2021-01-07 07:28

    In both cases you are getting iterator and not temporary collection. Iterator is using internal state machine to remember what is the current item, and it uses MoveNext method to get nex item.

    If you look at IL code you will see more details what is going on inside of foreach. Here is the IL for

    void Main()
    {
        var dictionary = new Dictionary { { 1, "one" }, { 2, "two" }};
    
        foreach (var item in dictionary.Values)
        {
            Console.WriteLine(item);
        }
    }
    

    IL Code:

    IL_0000:  nop         
    IL_0001:  newobj      System.Collections.Generic.Dictionary..ctor
    IL_0006:  stloc.1     
    IL_0007:  ldloc.1     
    IL_0008:  ldc.i4.1    
    IL_0009:  ldstr       "one"
    IL_000E:  callvirt    System.Collections.Generic.Dictionary.Add
    IL_0013:  nop         
    IL_0014:  ldloc.1     
    IL_0015:  ldc.i4.2    
    IL_0016:  ldstr       "two"
    IL_001B:  callvirt    System.Collections.Generic.Dictionary.Add
    IL_0020:  nop         
    IL_0021:  ldloc.1     
    IL_0022:  stloc.0     // dictionary
    IL_0023:  nop         
    IL_0024:  ldloc.0     // dictionary
    IL_0025:  callvirt    System.Collections.Generic.Dictionary.get_Values
    IL_002A:  callvirt    System.Collections.Generic.Dictionary+ValueCollection.GetEnumerator
    IL_002F:  stloc.2     
    IL_0030:  br.s        IL_0043
    IL_0032:  ldloca.s    02 
    IL_0034:  call        System.Collections.Generic.Dictionary+ValueCollection+Enumerator.get_Current
    IL_0039:  stloc.3     // item
    IL_003A:  nop         
    IL_003B:  ldloc.3     // item
    IL_003C:  call        System.Console.WriteLine
    IL_0041:  nop         
    IL_0042:  nop         
    IL_0043:  ldloca.s    02 
    IL_0045:  call        System.Collections.Generic.Dictionary+ValueCollection+Enumerator.MoveNext
    IL_004A:  brtrue.s    IL_0032
    IL_004C:  leave.s     IL_005D
    IL_004E:  ldloca.s    02 
    IL_0050:  constrained. System.Collections.Generic.Dictionary<,>+ValueCollection.Enumerator
    IL_0056:  callvirt    System.IDisposable.Dispose
    IL_005B:  nop         
    IL_005C:  endfinally  
    IL_005D:  ret         
    

提交回复
热议问题