2

まあ、言葉で説明するのは難しいです。だからここに例があります。SDL .NET APIにSpriteCollectionは、スプライトのコレクションになるように設計されたというクラスがあります。ただし、問題は、何らかの理由で、開発者が.NETクラスSpriteCollectionのように汎用を作成しないことを決定したことです。List<>だから、私は推測します、それはSpriteクラスまたはから継承する他のクラスでのみ機能することができSpriteますか?Tileとにかく、私がから派生したとしましょうSprite。そして、それに2つの新しいプロパティを追加します。

class Tile : Sprite
{

    public Tile(char symbol = default(char), bool solid = true)
    {
        Symbol = symbol;
        Solid = solid;
    }

    public char Symbol
    {
        get;
        set;
    }

    public bool Solid
    {
        get;
        set;
    }
}

では、どうすればSpriteCollectionwith Tilesを使用しても、次のTileような排他的プロパティを使用できるようになりSolidますか?

1つの(おそらくばかげた)解決策はおそらくこれでしょう:

Tile t = (Tile) myCollection[i];
if (t.Solid) { ... }

このようなことをするためのより良い方法はありますか?

4

3 に答える 3

3

SpriteCollectiontoの戻り値をキャストするというあなたの提案Tileは、それを行う方法です。提供されているコレクションクラスを使用する必要があり、それを変更できない場合、より良いオプションはありません。

于 2012-07-31T20:14:27.553 に答える
1

繰り返し処理するときにキャストを避けたい場合は、GetEnumeratorメソッドをオーバーライドできます。

public class TileList: SpriteList {

    public new IEnumerator<Tile> GetEnumerator()
    {
        foreach (var tile in GetBase())
        {
            if (tile is Tile)
            {
                yield return tile as Tile;
            }
        }
    }

    protected SpriteList GetBase()
    {
        return (SpriteList )this;
    }
}

(これはもちろんキャストしますが、そのキャストを列挙子にカプセル化します。)

于 2012-07-31T20:19:34.060 に答える
0

では、SpriteCollectionをTilesで使用し、SolidなどのTile専用プロパティを引き続き使用するにはどうすればよいですか?

これは、何らかの形式のキャストを介して行うことができます。私は個人的に使用しますが、あなたの方法は機能します:

Tile t = myCollection[i] as Tile;
if (t != null)
{
    if (t.Solid) { ... }
}

Tileこれにより、インスタンスだけでなく、他のスプライトもコレクションに安全に追加できます。

などのジェネリッククラスを使用する場合にも同じ問題が発生しますList<Sprite>Spriteこれにより、だけでなく、任意のサブクラスを使用できるようになりますTile。キャストせずにタイプセーフなコレクションを作成するにはList<Tile>、を使用する必要があります。これにより、コレクション内の他のスプライトではなく、タイルのみに制限されます。

于 2012-07-31T20:12:50.533 に答える