0

次のコードが示すように、メモリを節約するために、レコードのような構造体をいくつか定義し、それらのインスタンスを配列に格納しました。

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?
    }
}

上記のものがC/C ++で実装されている場合、コピーは発生しないことはわかっていますが、C#についてはよくわかりませんが、を?に置き換えるFoo[]とどうなりList<Foo>ますか?C#には参照を返すメカニズムがないため、理論的には、戻り値の最適化が含まれていない場合、インデクサーは参照型のポインター(4バイト)または値型のコピー全体を返します。では、この種のばかげたコピーが.NET / MONO jitによって回避されることが保証されているかどうか、誰か教えてもらえますか?

4

2 に答える 2

3

いいえ、値はコピーされません-arr[i]変数として分類されるため、Baz「インプレース」でフェッチされます。それを検証する方法を理解するのに少し時間がかかりましたが、プロパティに配列の値を変更させることで、ほぼ可能です...

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
    }
}

「Fooobj」に関するコメントは、C#では多少誤解を招く可能性があることに注意してください。ここにはオブジェクトがありません。タイプの値だけがありますFoo

于 2012-11-05T07:43:43.230 に答える
1
 for(var i = 1000000; i-- > 0;)
    { 
        baz = arr[i].Baz; //Will the Foo obj resides at arr[i] be copied?
    }

いいえ。オブジェクトのコピーをFoo実行するには、実際にFooオブジェクトを別の変数に割り当てる必要があります。

Foo foo = arr[i] ;//would copy the struct at arr[i] into foo. I'm pretty sure it is this case with C/C++.
于 2012-11-05T07:43:00.987 に答える