4

私は一連のオブジェクトを持っています。それらを建物と呼びましょう。各オブジェクトは、その建物に対して静的であるが、価格などの建物ごとに異なる特定のプロパティを共有しています。これを実装する最善の方法は、価格属性を共有する抽象スーパークラスを作成し、各サブクラスに値を設定することだと思いましたが、これを機能させる方法がわかりません。これが私が試したものの例です:

using System;
public abstract class Buildings
{
   internal static int price;
   internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
    public Walls()
    {
        price = 200;
        turnsToMake = 5;
    }
}

これは建設には問題なく機能しますが、作成する前に価格を確認したい場合 (プレイヤーが十分なお金を持っているかどうかを確認するため) は、null 値を返すだけです。とても簡単な修正だと確信していますが、わかりません。何か助けはありますか?

4

3 に答える 3

8

検討する価値のある、「まだら」でありながら単純な解決策があります。基本クラスを汎用クラスとして定義し、派生クラスで T をクラス自体として設定すると、機能します。

これは、.NET が新しい定義ごとに新しい型を静的に定義するために発生します。

例えば:

class Base<T>
{
    public static int Counter { get; set; }

    public Base()
    {
    }
}

class DerivedA : Base<DerivedA>
{
    public DerivedA()
    {
    }
}

class DerivedB : Base<DerivedB>
{
    public DerivedB()
    {
    }
}

class Program
{
    static void Main(string[] args)
    {

        DerivedA.Counter = 4;
        DerivedB.Counter = 7;

        Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
        Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7

        Console.ReadLine();
    }
}
于 2015-01-29T18:39:22.017 に答える
5

使用しないでくださいstatic。Static は、Building のすべてのインスタンスが同じ値を持つことを示します。派生クラスは、静的の独自のコピーを継承しません。ただし、基本クラスの静的は常に変更されます。あなたのデザインでは、price と turnToMake の値は 1 つだけです。

これはあなたのために働くはずです:

public abstract class Buildings
{
  internal int price;
  internal int turnsToMake;
}

ただし、最近ではほとんどの人がフィールドの使用を好まず、プロパティを好みます。

public abstract class Buildings
{
  internal int Price { get; set; }
  internal int TurnsToMake { get; set; }
}
于 2013-02-09T09:16:37.413 に答える
1

作成前に価格を確認したい […]

それが静的フィールドにたどり着いた方法だと思います。ただし、静的動作と仮想動作を組み合わせることはできません。つまり、サブクラスごとに静的フィールドを再宣言する必要があります。そうしないと、すべてのサブクラスがまったく同じフィールドを共有し、互いの値を上書きしてしまいます。

別の解決策は、.NET (4 以降) フレームワーク クラス ライブラリのLazy<T, TMetadata>型を使用することです。

public class Cost
{
    public int Price { get; set; }
    public int TurnsToMake { get; set; }
}

var lazyBuildings = new Lazy<Buildings, Cost>(
        valueFactory: () => new Walls(),
        metadata: new Cost { Price = 200, TurnsToMake = 5 });

if (lazyBuildings.Metadata.Price < …)
{
    var buildings = lazyBuildings.Value;
}

つまり、メタデータ ( .Metadata) は実際の型 ( BuildingsWalls) の外に存在し、そのインスタンス ( ) を実際に構築するかどうかを決定するために使用できます.Value

(ポリモーフィズムのおかげで、そのような「怠惰な工場」のコレクション全体を持ち、各工場のメタデータに基づいてインスタンス化する建物の種類を見つけることができます。)

于 2013-02-09T09:17:57.720 に答える