-1

私はC#プロジェクトに取り組んでおり、私のコードは次のようなものです:

public struct Point
{
    public int X;
    public int[,] arr;
}
List<Point> po=new List<Point>();
void func()
{
    Point p1;
    p1.arr = new int[1, 1];
    p1.X = 10;
    p1.arr[0, 0] = 1;
    func2(p2);
    p1.X=20;
    p1.arr[0,0]=10;
 }
void func2(Point h)
    {
        po.Add(h);
    }

このコードを追跡して func2 から戻ると、 p1.x を変更すると、リスト内のポイント (x パラメータ) は変更されませんが、p1.arr を 10 に変更すると、リスト内のポイント (arr パラメータ) も 1 から 10 に変更されます。なぜこれが起こったのか、この問題を解決するにはどうすればよいですか?

4

2 に答える 2

2

構造体には値のセマンティクスがあります。これは、p1.x を変更すると、参照ではなく値が変更されることを意味します。変更するローカル値 p1 があります。配列内の値を変更すると、その値のコピーが変更されます。

于 2013-03-06T21:57:47.977 に答える
1

構造体は C# の値の型ですが、クラスは参照です。ポイントを ref 修飾子で func2 に渡してみてください。

void func2(ref Point h){
    ....
}

実際、SD のコメントの JG のおかげで、次のようになります。

void func2(ref Point po, Point h){
    po.Add(h);
}

さらに調べてみると、それはまだ間違っています。基本的に、ポイントをリストに追加するときは、値によるポイントをリストにコピーしています。

p1 と po.Last() の値は同じですが、異なるオブジェクトを参照しています。Point がクラスである場合、この問題は発生しません。

p1 を po に追加した直後にこれを行うこともできますが、それは愚かで扱いにくいです:

po.Add(p1);
var len = po.Count;
po[len-1].X = 20;
po[len-1].arr[0,0]=10;

あなたはできません:

po.Add(p1);
var len = po.Count;
var pNew = po[len-1]; 
// p1 and pNew are different objects in memory, but with the same values
pNew.X = 20;
pNew.arr[0,0]=10;

技術的には、まさにそれを行うことができますが、それらはメモリ内の異なるオブジェクトであるため、期待どおりにはなりません。

深刻な必要がない限り、ポイントをクラスに切り替えるだけです。

于 2013-03-06T21:58:35.227 に答える