2

頭を壁にぶつける準備ができている

tiles という辞書を持つ Map というクラスがあります。

class Map
{
    public Dictionary<Location, Tile> tiles = new Dictionary<Location, Tile>();
    public Size mapSize;

    public Map(Size size)
    {
        this.mapSize = size;
    }
   //etc...

いくつかのことをテストするために、一時的にこの辞書に入力します..

public void FillTemp(Dictionary<int, Item> itemInfo)
    {
        Random r = new Random();
        for(int i =0; i < mapSize.Width; i++)
        {
            for(int j=0; j<mapSize.Height; j++)
            {
                Location temp = new Location(i, j, 0);

                int rint = r.Next(0, (itemInfo.Count - 1));

                Tile t = new Tile(new Item(rint, rint));

                tiles[temp] = t;
            }
        }

    }

そして私のメインプログラムコードで

Map m = new Map(10, 10);
m.FillTemp(iInfo);
Tile t = m.GetTile(new Location(2, 2, 0)); //The problem line

ここで、コードにブレークポイントを追加すると、マップ クラスのインスタンス (m) が上記の関数を介してペアで満たされていることがはっきりとわかりますが、GetTile 関数を使用して値にアクセスしようとすると、次のようになります。

    public Tile GetTile(Location location)
    {
        if(this.tiles.ContainsKey(location))
        {
            return this.tiles[location]; 
        }
        else
        {
            return null;
        }
    }

常に null を返します。繰り返しますが、Map オブジェクト内を表示し、 x=2,y=2,z=0 の Location キーを見つけると、値が FillTemp によって生成された Tile であることがはっきりとわかります。

なぜこれを行うのですか?これまでのところ、このような辞書で問題はありませんでした。null を返す理由がわかりません。繰り返しになりますが、デバッグ時に、 Map インスタンスに Location キーが含まれていることがはっきりとわかります...非常にイライラします。

手がかりはありますか?さらに情報が必要ですか?

助けていただければ幸いです:)

4

3 に答える 3

7

「場所」が何であるかは示していませんが、クラスの場合、これは通常の動作です。オブジェクトは、参照を比較することによって等しいかどうかがテストされます。そのため、コンテンツが同じであっても、Location の異なるインスタンスは常に等しくありません。

最も簡単な修正は、Location クラスの Equals() と GetHashCode()をオーバーライドすることです。そして、それを不変クラス (またはおそらく不変構造体) として (再) 設計することをお勧めします。

于 2010-03-14T17:12:42.573 に答える
1

ヘンクは正しいです。.Netで2つのオブジェクトが等しいかどうかをテストする場合、実際には「参照xが参照yと同じオブジェクトを指している」かどうかを尋ねています。

したがって、デフォルトでは:

Location a = new Location(2, 2, 0);
Location b = new Location(2, 2, 0);
Location c = a;

bool notEqual = ( a == b );  // false
bool equal = ( a == c );     // true

これを回避するには、Locationオブジェクトのequalityメソッドをオーバーライドして、equalityの値を比較する必要があります。Equalsたとえば、メソッドの本体は、次のように終了する可能性があります。

return (this.x == that.x && this.y == that.y && this.z == that.z);
于 2010-03-14T17:24:13.297 に答える
0

みんなありがとう!ほんとうにありがとう!

Location を値型にしたところ、問題なく動作しています。

コード全体を投稿できなくて申し訳ありませんが、それが必要だとは思わず、読者は location が x、y、z の int 値を持つ単純なクラスであると想定できると想定しました。

私は皆さんのおかげで多くの新しいことを学び、この (一般的に) 素晴らしい言語についての私の理解はそのおかげでより大きくなりました :o)

気をつけて、

于 2010-03-14T18:16:47.287 に答える