4
class Player
{
   private Location location;

   public Location getLocation()
   {
        return location;
   }

    public void setLocation(Location location)
    {
        this.location = location;
    }
}

...

class Location
{
    int x,y,z;

    public Location(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Location(Location location)
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }


    public void updateLocation(Location location) //the fix..
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }
}

言う..あなたがする

Player p1 = new Player();
Player p2 = new Player();
p1.setLocation(p2.getLocation());

他の人の場所を変更しようとすると、バグ/問題が発生します。両方のプレイヤーが同じ場所を共有するようになったため、両方のプレイヤーの場所がまったく同じように変更されます。

したがって、もちろん、以下は問題なく機能します。

p1.setLocation(new Location(p2.getLocation()));

しかし問題は、常に新しいオブジェクトを作成することです..既存のインスタンスを更新するだけでよいのに..? これを修正するために以下で行ったように、独自のメソッドを作成せずに、デフォルトで既存のインスタンスを更新するにはどうすればよいですか。

以下の方法を使用してこれを修正する必要がありました(以下のようにせずにデフォルトでこれを行う方法)

    public void setLocation(Location location)
    {
        if (this.location == null)
            this.location= new Location(location);
        else
            this.location.updateLocation(location);
    }

私が知らないかもしれないトリックを知っている人はいますか?ありがとう。

4

2 に答える 2

7

クラスは参照型です。これを呼び出すと:

p1.setLocation(p2.getLocation());

インスタンスデータをメソッドに渡すのではなく、インスタンスへの参照を渡します。参照は、インスタンスのデータが格納されているヒープ (メモリ) へのマネージド ポインターのようなものです。そうしないと、インスタンスのデータに対するすべての変更がメソッド スコープしか持たないため、これは非常に重要です。これを呼び出すと:

this.location = location;

データではなく参照を割り当てています。locationこれは、との両方this.locationがメモリ内の同じブロックを指すことを意味します。

これが C# プログラミングの要点です。データを参照する代わりにコピーする場合は、クラスの代わりに構造体を使用する必要があります。

とにかく、あるインスタンスから別のインスタンスに値を再割り当てすることは、非常に一般的なタスクです。

編集:

オーバーヘッドのために新しいオブジェクトを作成したくないと指摘しました。

  • 時期尚早の最適化は悪の元
  • それが理にかなっており、実際にパフォーマンスが低下していると思われる場所を最適化します。ここには、単純なラップトップでのオブジェクトのインスタンス化に関するいくつかの値があります。

また、プロパティが嫌いだと言うのは奇妙です-C#でプログラミングしているので、正しく使用しないと、同僚があなたを気に入らないでしょう.

于 2011-06-25T21:14:32.333 に答える
0

.NET での参照の受け渡しは、基本的に Java と同じです。ただし、.NET にはいくつかの追加機能があります。

たとえば、out および ref パラメーターを使用して、引数として渡された値を返すことができます。例えば

    public void SaveProductFeature(ref SaveCollection save)
    {
       SaveCollection.Product.ProductId = Product.Save(SaveCollection.Product);
    }
于 2011-06-29T07:16:07.077 に答える