Will copying occur if the methods of an array element, which is a value type object, are called?

StackOverflow https://stackoverflow.com/questions/13227856

Domanda

To save the memory, I defined some record-like structs and stored their instances in arrays, as the following code shows:

struct Foo
{
    readonly char _bar;
    readonly int _baz;
    // other probable fields ...
    public char Bar{get{return _bar;}}
    public int Baz{get{return _baz;}}

    public Foo(char bar, int baz){_bar = bar; _baz = baz;}
}

static void Main ()
{
    Foo[] arr = new Foo[1000000];
    int baz;
    for(var i = 1000000; i-- > 0;){ arr[i] = new Foo('x',42); }
    for(var i = 1000000; i-- > 0;)
    { 
        baz = arr[i].Baz; //Will the Foo obj resides at arr[i] be copied?
    }
}

I know the copying won't happen if the stuff above was implemented in C/C++, yet I'm not sure about C#, what if I replace the Foo[] with an List<Foo>? C# doesn't have a mechanism to return a reference, so theoretically the indexer would return either a pointer(4 bytes) for reference type or the whole copy for value type, if the return value optimization was not involved. So, could anyone tell me, whether this sort of ridiculous copying is guaranteed to be avoided by .NET/MONO jit ?

È stato utile?

Soluzione

No, the value isn't copied - arr[i] is classified as a variable, so Baz will be fetched "in place". It took me a while to work out how you could validate that, but it is just about possible, by making the property change the value in the array...

using System;

public struct Foo
{
    private int field;

    public int Value
    {
        get
        {
            Test.array[0].field = 10;
            return field;
        }
    }
}    

public class Test
{
    public static Foo[] array = new Foo[1];

    static void Main()
    {
        Console.WriteLine(array[0].Value); // Prints 10
    }
}

Note that your comment about "the Foo obj" is somewhat misleading in C# - there isn't an object here; there's just a value of type Foo.

Altri suggerimenti

 for(var i = 1000000; i-- > 0;)
    { 
        baz = arr[i].Baz; //Will the Foo obj resides at arr[i] be copied?
    }

Nope. For copy of the Foo object to occur you actually have to assign the Foo object to another variable.

Foo foo = arr[i] ;//would copy the struct at arr[i] into foo. I'm pretty sure it is this case with C/C++.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top