2016-07-02 2 views
0

J'ai une classe appelée "RelativeData" qui est utilisée pour comparer des valeurs à travers un automate fini. J'essaye de construire une classe qui prend des instantanés des données à des intervalles donnés. Les intervalles étant: StateBegins, StateMachineBegins, et celui avec lequel je rencontre un problème, liveValue. Le défi im ayant est le liveValue (s) que je souhaite suivre sont dans une classe distincte, Il ya une grande liste de valeurs que je veux ajouter à suivre avec mes objets RelativeData, donc ma classe doit être générique.C# Stocker une référence générique pour avoir des snapshots de mise à jour automatique

le but de cette classe est de prendre des instantanés de données.

class RelativeData<T> 
{ 
    T initialValue; 
    T stateValue; 
    T liveValue; //currently not implemented, since i can't store a ref 

    public void StateMachineActive(T curValue) 
    { 
    initialValue = curValue; 
    } 
    public void StateUpdated(T curValue) 
    { 
     stateValue = curValue; 
    } 
} 

ex) une float appelée "énergie" qui appartient à un sort. Lorsque la machine d'état active, il appelle StateMachineActive sur ma liste de relativeData, ce qui pourrait mettre à jour interne de préférence en utilisant liveValue, au lieu d'avoir à passer CurValue

fix actuel) j'ai un gestionnaire qui ajoute ces valeurs aux dictionnaires du générique les types.
Dictionary<myKey,relativeData<bool>> relativeBoolData
Dictionary<myKey,relativeData<float>> relativeFloatData
& etc ... Cependant pour appeler StateUpdated, je dois passer la valeur actuelle, que je dois obtenir d'un grand boîtier de commutateur à l'aide myKey. Faisable, mais de retour en C++ jours je pourrais juste stocker un T *. Impossible d'activer le mode non sécurisé car Unity ne semble pas l'autoriser. Je pourrais avoir les valeurs réelles juste stockées là, mais chaque fois que je veux obtenir le currentValue (qui arrive plus souvent que d'obtenir une valeur relative) partout dans le code, cela augmenterait la complexité (être plus lourd). Au moins, je suppose.

1) Puis-je stocker un pointeur sur un type Icomparable? Puis-je avoir un point liveValue vers un type de données valueType/Primitive (ie, int, long, enum) ailleurs, comme je le pourrais en C++ avec T *. Je sais que je peux passer en utilisant "ref" mais je n'arrive pas à le stocker. 2) Devrais-je simplement y stocker les valeurs réelles, et tout être récupéré par un commutateur à deux niveaux (d'abord savoir quel dict appeler, le float, bool ... et ensuite pour récupérer la valeur) cela n'augmenterait-il pas trop le temps d'exécution? Les valeurs non relatives: énergie, stabilité, etc., sont utilisées en continu dans les sorts pour les calculs internes. Le relatif seulement utilisé pour la machine d'état. (peut avoir 2 ~ 60 sorts actifs à la fois)

3) Est-ce juste un mauvais modèle, y at-il un meilleur modèle que je ne vois juste pas, une meilleure façon de prendre des instantanés de données génériques?

4) Je sais que les tableaux sont par référence, mais cela signifierait que mes données d'origine devraient toutes devenir des tableaux correctement?

5) Devrais-je le laisser tel quel. Cela fonctionne, juste un peu plus en désordre et plus lent.

tous sont IComparable: ints, flotteurs, Bools, énumérations ..

Répondre

0

Vous pouvez faire une des opérations suivantes:

  • Créer une classe wrapper pour les valeurs et garder une référence l'emballage.

    public class Wrapper<T> 
    { 
        public T Value { get; set; } 
    } 
    
  • Stockez les valeurs dans un tableau et souvenez-vous des index au lieu des valeurs elles-mêmes.
  • Stockez les valeurs dans un dictionnaire et mémorisez leurs clés au lieu des valeurs elles-mêmes.
  • Stockez un délégué accesseur (Func<T>). Remarque: Les expressions Lambda conservent automatiquement une référence sur le contexte dans lequel elles ont été déclarées pour la première fois. Voir The Beauty of Closures (par Jon Skeet).