2016-07-02 31 views
0

Ich habe eine Klasse namens "RelativeData", die für den Vergleich von Werten über eine Zustandsmaschine verwendet wird. Ich versuche eine Klasse zu erstellen, die Momentaufnahmen der Daten in bestimmten Intervallen erstellt. Die Intervalle sind: StateBegins, StateMachineBegins und der, mit dem ich Probleme habe, liveValue. Die Herausforderung, die ich habe, ist die liveValue (s), die ich verfolgen möchte, sind in einer separaten Klasse. Es gibt eine große Liste von Werten, die ich hinzufügen möchte, um meine RelativeData Objekte zu verfolgen, also muss meine Klasse generisch sein.C# Speichern einer generischen Referenz für selbstaktualisierende Snapshots

Der Punkt dieser Klasse ist es, Snapshots von Daten zu machen.

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) ein float "Energie" genannt, was zu einem Zauber gehört. Wenn die Zustandsmaschine aktiviert, ruft er StateMachineActive auf meiner Liste der relativeData, die vorzugsweise intern aktualisieren könnte liveValue verwenden, statt CurValue

Aktuelle fix passieren zu müssen) Ich habe einen Manager, der diese Werte Wörterbücher des generischen fügt Arten.
Dictionary<myKey,relativeData<bool>> relativeBoolData
Dictionary<myKey,relativeData<float>> relativeFloatData
& etc ... jedoch StateUpdated nennen, muss ich den aktuellen Wert zu übergeben, die ich brauche, von einem großen Schaltergehäuse bekommen myKey verwenden. Doable, aber in C++ Tagen konnte ich einfach ein T * speichern. Der unsichere Modus kann nicht aktiviert werden, da Unity dies nicht zulässt. Ich könnte die tatsächlichen Werte nur darin gespeichert haben, aber jedes Mal, wenn ich den currentValue (was viel öfter passiert, als einen relativen Wert zu erhalten) überall im Code bekommen würde, würde dies die Komplexität erhöhen (proc-heavy). Zumindest nehme ich an.

Frage: 1) Kann ich einen Zeiger auf einen kompatiblen Typ speichern? Kann ich liveValue auf einen valueType/Primitive Datentyp (dh int, long, enum) anderswo verweisen, wie ich es in C++ mit T * konnte. Ich weiß, ich kann "Ref" weitergeben, aber ich kann es nicht speichern.

2) Sollte ich stattdessen nur die tatsächlichen Werte in dort speichern, und alles durch einen zweistufigen Schalter Fall reerived (Zuerst zu wissen, welches Diktat, den Schwimmer, bool ... aufrufen und dann den Wert abrufen) Würde das die Laufzeit nicht zu stark erhöhen? Die nicht-relativen Werte: Energie, Stabilität usw. werden in Spells für interne Berechnungen fortlaufend verwendet. Der relative Wert wird nur für die Statusmaschine verwendet. (kann 2 bis 60 Sprüche gleichzeitig haben)

3) Ist das nur ein schlechtes Muster, gibt es ein besseres Muster, das ich gerade nicht sehe, eine bessere Möglichkeit, Schnappschüsse von generischen Daten zu machen?

4) Ich weiß Arrays sind durch ref, aber das würde bedeuten, meine ursprünglichen Daten müssten alle Arrays werden richtig?

5) Sollte ich es einfach so lassen wie es ist. Es funktioniert, nur ein bisschen unordentlicher und langsamer.

alle von ihnen sind IComparable: Ints, Schwimmern, bools, Aufzählungen ..

Antwort

0

Sie eine der folgenden Möglichkeiten:

  • eine Wrapper-Klasse erstellen, um die Werte für und einen Verweis auf halten die Verpackung.

    public class Wrapper<T> 
    { 
        public T Value { get; set; } 
    } 
    
  • Speichern Sie die Werte in einem Array und merken Sie sich die Indizes anstelle der Werte selbst.
  • Speichern Sie die Werte in einem Wörterbuch und merken Sie sich ihre Schlüssel anstelle der Werte selbst.
  • Speichern Sie einen Accessor-Delegaten (Func<T>). Hinweis: Lambda-Ausdrücke behalten automatisch einen Verweis auf den Kontext, in dem sie zuerst deklariert wurden. Siehe The Beauty of Closures (von Jon Skeet).