What variable type should I use to store types of

2019-08-14 02:05发布

问题:

README

  • I have thousands of creatures, and each creature derives from Creature.
  • An example of a creature is Creature_MoonDancer.
  • Creature is a class that can only be instantiated if a CreatureData object is passed into its constructor.
  • I want to find a way to scope any sealed type that inherits from Creature to one CreatureData in a Dictionary.
  • Each creature may only be linked up to a maximum of 1 instance of CreatureData in creatureDatabaseDictionary.

Here is CreatureData, a class with information that needs to be fed into Creature's constructor to instantiate it:

--CreatureData.cs

using UnityEngine.UI;

[System.Serializable]
class CreatureData {
    //To be set by Unity engine's inspector.
    [SerializeField] private Sprite creatureHead;
    [SerializeField] private int creatureStartingDamage;
    Sprite CreatureHead {
        get{
            return creatureHead;
        }
    }
    Sprite CreatureStartingDamage {
        get{
            return creatureStartingDamage;
        }
    }
}

Here I have an abstract class Creature which encompasses what a creature is.

--Creature.cs

public class Creature {
    protected Sprite creatureHead;
    protected int creatureDamage;
    public Creature(CreatureData creatureData){
        creatureHead = creatureData.CreatureHead;
        creatureDamage = creatureData.CreatureStartingDamage
    }
    public abstract void getAttackedBy(Creature other);
}

There are thousands of sealed creature types that derive from Creature and here is one example:

--Creature_MoonDancer.cs

public sealed class Creature_MoonDancer : Creature{
    private int moonOrbsInPossession;
    public Creature_MoonDancer (CreatureData creatureData, int startingMoonOrbs) : base(creatureData){
        moonOrbsInPossession = startingMoonOrbs;
    }
    public override void getAttackedBy(Creature other){
        if(moonOrbsInPossession > other.creatureDamage){
            Debug.Log("MoondancerWins");
        }
        else if(Random.value < 0.5)
            Debug.Log("MoondancerDies");
        else
            Debug.Log("MoondancerWins");
    }
}

CreatureDatabase will contain a Dictionary that stores CreatureData and links any sealed class that derives from Creature to up to 1 corresponding CreatureData as such:

--CreatureDatabase.cs

public class CreatureDatabase : MonoBehaviour {
    private static class CreatureDataCustomSerializableDictionary
        : CustomSerializableDictionary<typeof(Creature),CreatureData> {}
    //TODO: Create custom property drawer for CustomSerializableDictionary
    [SerializeField] private CreatureDataCustomSerializableDictionary creatureDatabaseDictionary;

    public CreatureDatabaseDictionary {
        get{
            return creatureDatabaseDictionary;
        }
    }
}

Here is the game manager trying to get values out from the creatureDatabaseDictionary Dictionary:

--GameManager.cs

public class GameManager : MonoBehaviour{
    [SerializeField] private CreatureDatabase creatureDatabase;
    private Creature SummonMoonDancer(){
        CreatureData creatureData;
        bool success = creatureDatabase.CreatureDatabaseDictionary.TryGetValue(typeof(Creature_MoonDancer), out creatureData);
        if(success == false){
            Debug.LogError("Tried summoning MoonDancer when creature database did not have a typeof(MoonDancer) key");
        }
        else{
            return new Creature_MoonDancer(creatureData), Player.GetInt("NumberOfMoonorbsInPlayersPouch");
        }

    }
}

Here are some of the project requirements:

  • The game balancing team are required to balance the game without modifying code.
  • Important: The game balancing team must not be able to insert any keyvaluepairs with keys that are not creature types.

回答1:

Here's your code written so that it compiles with an example assignment:

public interface mybaby {}
public class mytom : mybaby {}
public class mydick : mybaby {}
public class myharry : mybaby {}

public class Test
{
    mybaby mychild = new myharry();
}

This is working, valid, C# code.