Question

Vous cherchez un moyen de passer un tableau associatif à une méthode. Je cherche à réécrire un paquet tween Actionscript en C #, mais en cours d'exécution en difficulté avec les tableaux / objets « associatifs ». Normalement, en Actionscript je pourrais faire quelque chose comme:

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

Et cela pourrait être appelé comme:

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

Je suis à la recherche d'un moyen de faire la même chose en C #. Jusqu'à présent, j'ai rassemblé mes options à:

a) la création d'une classe ou struct pour définir les clés possibles et les types et param passer que

b) transmettre les paramètres en tant que type générique

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

en supposant

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

et trouver un moyen d'utiliser que la fonction d'interpolation (je ne sais pas comment séparer la clé = étant donné que l'objet de valeur. Des idées?)

c) créer un Dictionary<string, object> pour passer les paramètres à la fonction d'interpolation

D'autres idées ou des exemples de code? Je suis nouveau sur C #.

Modifier

m'a pris toute la journée pour comprendre cela:

"Les types anonymes ne peuvent pas être partagées à travers les frontières de l'Assemblée. Le compilateur assure qu'il ya au plus un type anonyme pour une séquence donnée de paires nom de la propriété / de type dans chaque assemblage. Pour passer des structures entre les assemblées, vous aurez besoin de les définir correctement ».

Était-ce utile?

La solution

EDIT : Ceci est essentiellement le mécanisme qui HtmlHelper extensions utilisent dans ASP.NET MVC. Ce n'est pas original avec moi.


Je préfère une approche hybride qui a deux signatures différentes. Note: Je ne l'ai pas essayé et il peut y avoir un conflit entre les deux signatures afin que vous pourriez avoir à donner la deuxième méthode un nom légèrement différent pour permettre au compilateur de choisir entre eux, mais je ne pense pas

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" ))
    {
      ....
    }
}

Ensuite, vous avez une classe ParameterDictionary qui utilise la réflexion sur le type anonyme et met en place le dictionnaire.

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);
             }
         }
    }
}

Cela vous donne à la fois la facilité d'utilisation et la facilité de consommation - les trucs de réflexion « laid » est enveloppé dans le constructeur unique pour le dictionnaire plutôt que dans votre méthode. Et, bien sûr, le dictionnaire peut être utilisé à plusieurs reprises à des fins similaires avec le code de réflexion écrit seulement une fois.

Autres conseils

Le dictionnaire est une approche raisonnable. Il pourrait ressembler à ceci:

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

l'esprit que lorsque vous passez les valeurs, vous pouvez utiliser la syntaxe raccourcie pour le rendre plus facile, comme d'initialisation de collection:

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

Ce serait un moyen assez rapide à faire à peu près « la même chose » que le code ActionScript, mais ce n'est pas vraiment génial C #. Le C # façon ish de le faire serait de faire un véritable TweenParameters struct ou classe avec des propriétés pour chaque paramètre possible, puis créer un pour passer dans tween (). Ceci est généralement considéré comme plus maintenable, puisque toutes les propriétés « disponibles » sont évidents à un appelant sans regarder dans les entrailles de tween (), et parce qu'il attrape des erreurs à la compilation qu'une comparaison de chaîne ne remarquerait pas avant l'exécution, comme typoing "durée" "duratoin".

Je suis fan de l'option (b) moi-même -. Le passage d'un type anonyme et l'analyse syntaxique les valeurs en utilisant la réflexion

Je l'ai vu d'autres réaliser la même chose en utilisant des expressions lambda. La syntaxe d'appel serait:

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

Et la déclaration serait quelque chose le long des lignes de:

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

L'idée est que vous pouvez prendre un nombre variable de « fonctions qui retournent un objet ». Vous analysez ensuite le nom du paramètre de chaque Expression et appeler chacun pour obtenir sa valeur.

Je ne pense pas que ce soit mieux que de réfléchir sur un type anonyme, mais il est une autre approche à considérer.

Mise à jour

Je l'ai fait écrit sur l'idée de passer des tableaux associatifs comme des dictionnaires sur mon blog, ici et .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top