Pregunta

Buscando una manera de pasar un arreglo asociativo a un método. Estoy mirando para reescribir un paquete de Tween Actionscript en C #, pero meterse en problemas con matrices / objetos "asociativos". Normalmente en Actionscript yo podría hacer algo como:

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

Y esto podría ser llamado como:

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

Estoy buscando una manera de hacer lo mismo en C #. Hasta ahora, he reunido mis opciones para ser:

a) la creación de una clase o estructura para definir las claves param y tipos posible y pasar esa

b) pasar los parámetros como tipo genérico

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

suponiendo

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

y buscar la manera de usar que en la función de interpolación (no estoy seguro de cómo separar la clave = valor de ese objeto dado. Alguna idea?)

c) crear un Dictionary<string, object> para pasar los parámetros en la función de interpolación

Cualquier otra idea o código de ejemplo? Soy nuevo en C #.

Editar

Me llevó todo el día para resolver esto:

"Los tipos anónimos no se pueden compartir a través de límites de montaje. El compilador asegura que hay a lo sumo un tipo anónimo para una determinada secuencia de pares de nombre de la propiedad / tipo dentro de cada montaje. Para pasar estructuras entre los conjuntos que tendrá que definir adecuadamente . "

¿Fue útil?

Solución

Editar : Este es básicamente el mecanismo que utilizan las extensiones HtmlHelper en ASP.NET MVC. No es original conmigo.


Me favorecer un enfoque híbrido que tiene dos firmas diferentes. Nota: No he probado esto y puede haber un conflicto entre las dos firmas lo que puede tener para dar el segundo método un nombre ligeramente diferente para permitir que el compilador para elegir entre ellos, pero yo no lo creo

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

A continuación, tiene una clase ParameterDictionary que utiliza la reflexión sobre el tipo anónimo y configura el diccionario.

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

Esto le da tanto la facilidad de uso y facilidad de consumo - la materia de reflexión "feo" está envuelto en el único constructor para el diccionario en lugar de en su método. Y, por supuesto, el diccionario se puede utilizar una y otra vez para fines similares con el código reflexión escrita solamente una vez.

Otros consejos

El diccionario es un enfoque razonable. Se podría tener este aspecto:

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

Mente que cuando se pasa los valores de la sintaxis de la colección de inicialización, puede utilizar acortado para que sea más fácil, como:

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

Esta sería una forma muy rápida de hacer más o menos "el mismo" que el código ActionScript, pero no es realmente grande C #. La forma -ish C # para hacerlo sería hacer un verdadero TweenParameters estructura o clase con propiedades para cada parámetro posible, y luego crear una para pasar a Tween (). Esto se considera generalmente más fácil de mantener, ya que todas las propiedades "disponibles" son obvias para una persona que llama sin mirar en la parte interna de Tween (), y debido a que captura los errores en tiempo de compilación que una comparación de cadenas no se diera cuenta hasta que el tiempo de ejecución, como typoing "duración" "duratoin".

Soy un fan de la opción (b) a mí mismo -. Pasando un tipo anónimo y analizar los valores utilizando la reflexión

He visto a otros a lograr lo mismo usando las expresiones lambda. La sintaxis llamar sería:

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

Y la declaración sería algo a lo largo de las líneas de:

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

La idea es que se puede tomar un número variable de "funciones que devuelven objeto". A continuación, analizar el nombre del parámetro de salida de cada Expresión , e invocar cada uno para obtener su valor.

No creo que esto es mejor que lo que refleja más de un tipo anónimo, pero es otra opción a considerar.

Actualizar

De hecho, he escrito acerca de la idea de pasar matrices asociativas como diccionarios en mi blog, aquí y aquí .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top