9

紹介として、私は個人的な学習目的で基本的な Quadtree エンジンを作成しています。このエンジンには、さまざまな種類の形状 (現在は円と四角形を使用しています) を処理する機能を持たせたいと考えています。これらの形状はすべてウィンドウ内を移動し、衝突が発生したときに何らかのアクションを実行します。

これまでに持っている形状オブジェクトは次のとおりです。

public class QShape {
    public int x { get; set; }
    public int y { get; set; }
    public string colour { get; set; }
}

public class QCircle : QShape {
    public int radius;
    public QCircle(int theRadius, int theX, int theY, string theColour) {
        this.radius = theRadius;
        this.x = theX;
        this.y = theY;
        this.colour = theColour;
    }
}

public class QSquare : QShape {
    public int sideLength;
    public QSquare(int theSideLength, int theX, int theY, string theColour) {
        this.sideLength = theSideLength;
        this.x = theX;
        this.y = theY;
        this.colour = theColour;
    }
}

ここで私の質問は、List<T> QObjectList = new List<T>();C# で一般的なリスト ( ) を作成して、異なるプロパティを持つ可能性のあるこれらのさまざまな形状をすべて含む 1 つのリストを作成する方法です (たとえば、QCircle には「radius」プロパティがあり、QSquare には「sideLength」プロパティがあります)。 )? 実装例も参考になります。

この質問にはばかばかしいほど明白な答えがあることは知っていますが、とにかく助けていただければ幸いです。私は C# に戻ろうとしています。明らかに久しぶり…

4

8 に答える 8

3

を実装する必要がありInterfaceます。例えば

public interface IHasLength
{
    int Length;
}

次に、実装で行うことができます

public class QSquare : QShape, IHasLength {
    public int sideLength;
    public QSquare(int theSideLength, int theX, int theY, string theColour) {
        this.sideLength = theSideLength;
        this.x = theX;
        this.y = theY;
        this.colour = theColour;
    }
    public int Length { get { return sideLength; } }
}
public class QCircle : QShape, IHasLength {
    public int radius;
    public QSquare(int theSideLength, int theX, int theY, string theColour) {
        this.sideLength = theSideLength;
        this.x = theX;
        this.y = theY;
        this.colour = theColour;
    }
    public int Length { get { return radius; } }
}

最後に、あなたのリストで:

List<IHasLength> shapesWithSomeLength = new List<IHasLength>();

これで、リストには、、、、またはが実装されている限り、それがであるかどうかを実装するものをIHasLengthすべて保持できます。QCircleQShapeQDuckIHasLength

于 2012-07-06T01:15:24.223 に答える
2

それらをに保存することはできますList<QShape>が、これはタイプ固有のプロパティにアクセスできないことを意味します。

一般に、基本クラスに共通のインターフェースを提供し、サブクラスの動作をオーバーライドすることで、これにアプローチできます。このように、共通のインターフェースは多様な行動の束を隠すことができます。たとえば、Growメソッドは、さまざまな形状の成長するアイテムの複雑さを隠すことができ、操作対象の形状を明示的に知らなくても呼び出すことができます。

public abstract class QShape {
    public abstract void Grow(int amt);
}
public class QSquare : QShape {
    private int sideLength;
    public override void Grow(int amt)
    {
        sideLength+=amt;
    }
}
public class QCircle : QShape {
    private int radius;
    public override void Grow(int amt)
    {
        radius+=amt;
    }
}
于 2012-07-06T01:15:49.213 に答える
1

何か足りない気がするけど…

List<QCircle> circleObjects = new List<QCircle>();

List<QSquare> squareObjects = new List<QSquare>();

完全にうまく機能します。

編集:

ああ、何を聞かれているのか分からなかった。

はい、あなたのQCircleQSquareクラスは から継承するので、そのままQShape実行できます。

List<QShape> shapes= new List<QShape>();

radiusそのリスト内のすべての のプロパティにアクセスしたい場合QCircleは、タイプに基づいてリストをフィルタリングする必要があることに注意してください。

于 2012-07-06T01:09:15.023 に答える
-1

保管

クラス定義はすでに正しい方向に進んでいます。あなたがしなければならないのは、あなたのすべての形を保持することができるListスーパークラス(この場合は)を作ることです。QShape

これがあなたがそれを作る方法の例です:

List<QShape> objects = new List<QShape>();

objects.add(new QCircle(...));
objects.add(new QSquare(...));

アクセス

ここでの問題は、すべてがリストに含まれると何が何であるかを区別することです。これは、C#のgetType()andメソッドを使用して行われます。typeof()Jon Skeetは、これを行う方法について優れた回答をしています)。基本的に、次のようになります。

if(objects.get(some_position).getType() == typeof(QCircle))
  QCircle circle = objects.get(some_position);
else if(/* like above with QSquare */)
  QSquare square = objects.get(some_position);

これを行った後、通常のようにオブジェクトの使用を再開できます。ただし、リストからそれらにアクセスしようとすると、QShapeリストに配置されたすべてのオブジェクトがそれにキャストされるため、持っているメソッドと変数のみを使用できます。

于 2012-07-06T01:20:24.237 に答える