Frage

Suche nach einer Möglichkeit, eine assoziative Array auf ein Verfahren zu übergeben. Ich suche ein Actionscript-Tween-Paket in C # neu zu schreiben, aber in Schwierigkeiten mit „assoziativen“ Arrays / Objekten ausgeführt wird. Normalerweise in Actionscript Ich könnte so etwas tun:

public function tween(obj:DisplayObject, params:Object = null):void {
    if (params.ease != null) {
        //do something
    }
    //...
}

Und das könnte so genannt werden:

tween(this, {ease:'out', duration:15});

Ich bin auf der Suche nach einer Möglichkeit, das gleiche in C # zu tun. Bisher habe ich meine Möglichkeiten gesammelt werden:

a) eine Klasse oder Struktur zu schaffen, die möglichen param Schlüssel und Typen zu definieren und zu übergeben, dass

b) übergeben, die Parameter als generischer Typ

tween(frameworkElement, new {ease = 'out', duration = 15});

angenommen

public static void tween(FrameworkElement target, object parameters);

und einen Weg herauszufinden, dass die Verwendung in der Tween-Funktion (ich bin nicht sicher, wie der Schlüssel zu trennen = Wert gegeben, das Objekt. Irgendwelche Ideen?)

c) Schaffung eines Dictionary<string, object> die Parameter in die Tween-Funktion zu übergeben

Jede andere Ideen oder Beispielcode? Ich bin neu in C #.

Bearbeiten

Hat mich den ganzen Tag um dies herauszufinden:

"Anonyme Typen können nicht über Montage Grenzen geteilt werden. Der Compiler stellt sicher, dass es höchstens einen anonymen Typ für eine bestimmte Abfolge von Eigenschaftsnamen / Typ-Paare innerhalb jeder Baugruppe ist. Um passieren Strukturen zwischen Baugruppen müssen Sie sie richtig definieren ".

War es hilfreich?

Lösung

Bearbeiten : Das ist im Grunde der Mechanismus, die Htmlhelper Erweiterungen in ASP.NET MVC verwenden. Es ist nicht original mit mir.


Ich würde einen hybriden Ansatz bevorzugen, die zwei verschiedene Signaturen hat. Anmerkung: Ich habe nicht versucht, und es kann ein Konflikt zwischen den beiden Unterschriften, so dass Sie die zweite Methode einen etwas anderen Namen geben müssen, kann der Compiler zu ermöglichen, zwischen ihnen zu wählen, aber ich glaube nicht, so

public static void tween( FrameworkElement target, object parameters )
{
    return tween( target, new ParameterDictionary( parameters ) );
}

public static void tween( FrameworkElement target,
                          ParameterDictionary values )
{
    if (values.ContainsKey( "ease" ))
    {
      ....
    }
}

Dann haben Sie eine ParameterDictionary Klasse, die Reflexion über den anonymen Typ verwendet und das Wörterbuch einrichtet.

public class ParameterDictionary : Dictionary<string,object>
{
    public ParameterDictionary( object parameters )
    {
         if (parameters != null)
         {
             foreach (PropertyInfo info in parameters.GetType()
                                                     .GetProperties())
             {
                 object value = info.GetValue(parameters,null);
                 this.Add(info.Name,value);
             }
         }
    }
}

Das gibt Ihnen sowohl einfache Bedienung und die einfachen Verbrauch - das „hässlich“ Reflexion Zeug ist in dem einzigen Konstruktor für das Wörterbuch eingewickelt, anstatt in Ihrer Methode. Und natürlich kann das Wörterbuch über und über mit dem Reflexions Code für ähnliche Zwecke verwendet werden, nur einmal geschrieben werden.

Andere Tipps

Das Wörterbuch ist ein sinnvoller Ansatz. Es könnte wie folgt aussehen:

public static void tween(FrameworkElement target, IDictionary<string, object> parameters)
{
    if (parameters.ContainsKey("ease")) {
        //do something
    }
}

Geist, dass, wenn Sie die Werte in geben, können Sie verkürzt Sammlung Initialisierung Syntax verwenden, um es einfacher, wie:

tween(something, new Dictionary<string, object> { { "ease", "out" }, { duration, 15 } });

Das wäre eine ziemlich schnelle Art und Weise sein, in etwa „das Gleiche“, wie der Actionscript-Code zu tun, aber es ist nicht wirklich toll C #. Die C # -ish Weg, es zu tun, wäre eine echte TweenParameters Struktur oder Klasse mit Eigenschaften für jeden möglichen Parameter zu machen, und dann erstellen in Tween () übergeben. Dies wird im Allgemeinen besser verwaltbar betrachtet, da alle „verfügbaren“ Eigenschaften zu einem Anrufer offensichtlich sind, ohne Blick in die Interna von Tween (), und weil sie Fehler bei der Kompilierung-Zeit fängt die ein String-Vergleich würde bemerken, die nicht erst zur Laufzeit, wie typoing "Dauer" "duratoin".

Ich bin ein Fan von Option (b) selbst -. Einen anonymen Typ vorbei und die Werte mithilfe von Reflektion Parsen aus

Ich habe andere gesehen, die gleiche Sache mit Lambda-Ausdrücke erreichen. Der Aufruf Syntax wäre:

tween(frameworkElement, ease => "out", duration => 15);

Und die Erklärung wäre etwas entlang der Linien der folgenden sein:

public static void tween(FrameworkElement target, params Expression<Func<object>>[] parameters) { ... }

Die Idee ist, dass Sie eine variable Anzahl von „Funktionen, das Objekt zurückgeben“ zu nehmen. Sie analysieren dann den Namen des Parameters aus jedem Expression und ruft jeden seinen Wert zu erhalten.

Ich glaube nicht, das ist besser als über eine anonyme Art reflektiert, aber es ist ein weiterer Ansatz zu berücksichtigen.

Aktualisieren

Ich habe geschrieben tatsächlich über die Idee der Weitergabe assoziative Arrays als Wörterbücher auf meinem Blog, hier und hier .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top