Indexers in List vs Array

前端 未结 6 2024
误落风尘
误落风尘 2020-12-10 04:30

How are the Indexers are defined in List and Arrays.

List lists=new List(); where MyStruct is a Structure.

6条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-10 04:55

    The final point:

    lists[0]._x=5
    

    is actually just a restatement of your earlier point:

    arr[0] gives a reference to the first Structure item.But lists[0] gives me a copy of it.

    If you edited a copy of it, the change would be lost into the ether, i.e.

    var throwawayCopy = lists[0];
    throwawayCopy._x = 5;
    // (and never refer to throwawayCopy again, ever)
    

    Since that is almost certainly not what you intended, the compiler doesn't let you. However, mutable structs are evil. A better option here would be don't use mutable structs. They bite.


    Taking this down a level, to a simple but concrete example:

    using System;
    struct Evil
    {
        public int Yeuch;
    }
    public class Program
    {
        public static void Main()
        {
            var pain = new Evil[] { new Evil { Yeuch = 2 } };
            pain[0].Yeuch = 27;
            Console.WriteLine(pain[0].Yeuch);
        }
    }
    

    This compiles (looking at the last 2 lines here) as:

    L_0026: ldloc.0 <== pain
    L_0027: ldc.i4.0 <== 0
    L_0028: ldelema Evil <== get the MANAGED POINTER to the 0th element
                               (not the 0th element as a value)
    L_002d: ldc.i4.s 0x1b <== 27
    L_002f: stfld int32 Evil::Yeuch <== store field
    
    L_0034: ldloc.0 <== pain
    L_0035: ldc.i4.0 <== 0
    L_0036: ldelema Evil <== get the MANAGED POINTER to the 0th element
                               (not the 0th element as a value)
    L_003b: ldfld int32 Evil::Yeuch <== read field
    L_0040: call void [mscorlib]System.Console::WriteLine(int32) <== writeline
    L_0045: ret 
    

    It never actual talks to the struct as a value - no copies, etc

提交回复
热议问题