5

簡単に言えば私の問題:

class A
{
   /* Other stuff in my class*/
    protected static staticMember;
}

class B : A
{
   /* Other stuff in my class*/
   // Will have A.staticMember but I want B.staticMember (same type)
}

class C : A
{
   /* Other stuff in my class*/
   // Will have A.staticMember but I want C.staticMember (same type)
}

したがって、すべての派生クラスに、その特定のクラスで共有される共有データが必要ですが、基本クラスで定義された共通の署名があります。

私は自由な時間に楽しむために単純な RTS ゲームを作成しています。いくつかの基本的な属性を持ついくつかの種類のユニット (宇宙船、建物など) があります。これらのユニットはプレイヤーがアップグレードできます (同じプレイヤーに属する同じタイプのすべてのユニットがアップグレードされます。たとえば、プレイヤー A が戦車の装甲をアップグレードすると、すべての戦車の装甲が向上します)。

これを達成しようとした方法は次のとおりです。

abstract class Unit
{
    /*several methods that is common for all units*/

    /*We don't know the unit's attributes at this point*/
    protected abstract double getMaxHitpoints();
    protected abstract double getFusionArmor();
    protected abstract double getNormalArmor();
    // and more similar abstract methods to come.

    double maxHitpoints;
    double fusionArmor;
    double normalArmor;
    //...

    // This method is called on construction and after upgrade completion.
    public void cacheAttributes(Player forPlayer)
    {
        Upgrade upgradesForThisUnit; //<<< Upgrade is class that is used like a struct to hold the upgrades for this kind of unit.
        upgrades.TryGetValue(forPlayer,out upgradesForThisUnit); ///< get upgrades if available (if not available it will give the default value [=no bonuses])

        maxHitpoints=getMaxHitpoints()+upgradesForThisUnit.hitpointBonus;
        fusionArmor=getFusionArmor()+upgradesForThisUnit.fusionArmorBonus;
        normalArmor=getNormalArmor()+upgradesForThisUnit.normalArmorBonus;
        //...
    }
    // This data structure is intended to hold the upgrades for every player for this kind of the unit
    // but unfortunally derived classes have this instance too so if the player upgrades the tanks it will upgrade the interceptors, peasants, buildings too...

    protected static Dictionary<Player,Upgrade> upgrades; 
}

class Tank : Unit
{
    protected override double getMaxHitpoints() {return 1000;}
    protected override double getFusionArmor() {return 10;}
    protected override double getNormalArmor() {return 50;}
    //...
}

辞書に追加のキーを追加することを考えました (ネストされた辞書を使用): 構造体をキーとして入力し、次のようにコードを変更します。

protected static Dictionary<Player,Dictionary<Type,Upgrade>> upgrades; 

public void cacheAttributes(Player forPlayer)
{
    Dictionary<Type,Upgrade> upgradesForThePlayer;
    upgrades.TryGetValue(forPlayer,out upgradesForThePlayer);

    Upgrade upgradesForThisUnit; //<<< Upgrade is class that is used like a struct to hold the upgrades for this kind of unit.
    upgradesForThePlayer.TryGetValue(GetType(),out upgradesForThisUnit); ///< get upgrades if available (if not available it will give the default value [=no bonuses])

    maxHitpoints=getMaxHitpoints()+upgradesForThisUnit.hitpointBonus;
    fusionArmor=getFusionArmor()+upgradesForThisUnit.fusionArmorBonus;
    normalArmor=getNormalArmor()+upgradesForThisUnit.normalArmorBonus;
    //...
}

しかし、これが期待どおりに機能するかどうかはわかりません。

解決策はおそらく簡単ですが、今これを解決する方法がわかりません。

4

3 に答える 3

1
    public class Singleton<T>
    {
        private static string _value;
        public string Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
            }
        }
    }
    public class At<T>
    {
        public static Singleton<T> field = new Singleton<T>();
    }

    public class Bt : At<Bt>
    {
    }

    public class Ct : At<Ct>
    {
    }
...
    Bt.field.Value = "bt";
    Ct.field.Value = "ct";
于 2009-11-21T20:41:33.777 に答える
0

辞書の辞書によって、おおよそ次のようなことを意味するDictionary<Player, Dictionary<Type, Upgrade>>場合、はい、それは期待どおりに機能し、述べられている問題の優れた解決策です。最大プレイヤー数が少ない場合は、Dictionaries の配列を使用することもできます。実際には、4 つの値をハッシュしてもあまり有用なものは得られません。(プレイヤーが最大4人の場合)

于 2009-11-21T19:02:47.250 に答える
0

かなり古い質問ですが、将来の人々に利益をもたらすために、同様の問題を回避する方法を次に示します。

class A
{
    /* Other stuff in my class*/
    protected MyClass nonStaticMember;
}

class B : A
{
    private static B _instance;
    public static B instance
    {
        get
        {
            return _instance;
        }
    }
    static B()
    {
        _instance = new B();
    }
    /* Other stuff in my class*/
    // Will have B.instance.nonStaticMember
}

class C : A
{
    private static C _instance;
    public static C instance
    {
        get
        {
            return _instance;
        }
    }
    static C()
    {
        _instance = new C();
    }   
    /* Other stuff in my class*/
    // Will have C.instance.nonStaticMember
}

C.instance.doSomethingTo_nonStaticMember()これは、別のクラスからアクセスする可能性があることを前提としています。

于 2011-11-18T08:00:19.730 に答える