es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Parámetro de acción con posibles múltiples argumentos

Tengo una función WaitAndRun. Quiero que este método sea muy genérico.

public static IEnumerator WaitAndRun<T>(float time, Action<T> action, object arg)
{
    yield return new WaitForSeconds(time);
    action((T)arg);
}

Funciona perfectamente con el siguiente ejemplo:

void an_action(int x)
{
    Debug.Log(x);
}
//...
WaitAndRun<int>(1, an_action, 2);

El problema es que quiero usar la misma definición cuando necesito múltiples argumentos también. ¿Cómo puedo hacer que esta función admita llamar tanto con un solo argumento como con múltiples argumentos al mismo tiempo? Por ejemplo:

void another_action(int x, int y);

Si uso object[] args en lugar de object arg, no estoy seguro de cómo modificar el resto de la función.

Edit: cambie “func” por “action”

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para hacer que la función WaitAndRun admita la llamada de argumentos individuales y múltiples al mismo tiempo, podemos modificar la función para que acepte un params object[] args en lugar de un solo object arg. Luego necesitaremos modificar la parte restante para pasar correctamente los argumentos al delegado action.

    Aquí está la función modificada:

    public static IEnumerator WaitAndRun<t>(float time, Action<t> action, params object[] args)
    {
        yield return new WaitForSeconds(time);
        
        // Comprobar si no hay argumentos
        if(args == null || args.Length == 0)
        {
            action(default(T));
            return;
        }
        
        // Comprobar si solo hay un argumento
        if(args.Length == 1)
        {
            action((T)args[0]);
            return;
        }
        
        // Si hay varios argumentos, crear un delegado con la firma correcta e invocarlo con los argumentos
        Type[] argTypes = new Type[args.Length];
        for(int i = 0; i < args.Length; i++)
        {
            argTypes[i] = args[i].GetType();
        }
        Type delegateType = Expression.GetActionType(argTypes);
        Delegate del = Delegate.CreateDelegate(delegateType, action.Target, action.Method);
        del.DynamicInvoke(args);
    }
    

    Explicación:

    • Agregamos la palabra clave params al parámetro args, lo que nos permite pasar cualquier cantidad de argumentos.
    • Primero comprobamos si no hay argumentos o solo hay un argumento, en cuyo caso simplemente llamamos al delegado action con el valor predeterminado o el único argumento.

    • Si hay varios argumentos, utilizamos Reflexión para crear un nuevo delegado con la firma correcta (es decir, que coincida con el delegado action). Luego invocamos este nuevo delegado con los argumentos.

    Con estas modificaciones, ahora podemos llamar a la función WaitAndRun con cualquier número de argumentos:

    csharp
    WaitAndRun<int>(1, un_action, 2);
    WaitAndRun<int>(1, otro_action, 2, 3);
    WaitAndRun<string>(1, otro_action, "hola", 5);
    WaitAndRun<float>(1, otro_action, 1.2f, 3.4f);

Comments are closed.