03/10/26 · 4 min de lectura

Delegates en C#

Cómo crear y utilizar delegados para proporcionar una funcionalidad compleja y dinámica en sus scripts.

Imagen por Artur Shamsutdinov .

Los delegados te permiten crear comportamientos robustos y complejos dentro de tus scripts. Un delegado puede considerarse simplemente como un contenedor para una función que puede pasarse de un lado al otro o usarse como una variable.

Al igual que las variables, a los delegados se les puede asignar valores y estos valores pueden cambiarse durante el runtime. La diferencia es que, mientras que las variables contienen datos, los delegados contienen funciones.

quí tenemos una escena con un GameObject dentro. El GameObject tiene un DelegateScript anexado. Vamos a monitorear el resultado de la escena en la vista Console.

En el DelegateScript, lo primero que hacemos es declarar nuestra plantilla del delegado. Esta plantilla va a dictar exactamente qué tipos de métodos pueden asignarse a nuestro delegado.

Creamos un delegado con la palabra reservada delegate. Lo que sigue a una palabra reservada delegate es la firma del delegado. Al igual que una función, nuestro delegado tiene un tipo de retorno, un nombre y una lista de parámetros.

delegate void MyDelegate(int num);

En este ejemplo, podemos ver que para que se le asigne un método a este delegado, debe tener un retorno tipo void y toma un solo parámetro de tipo entero.

Después de que creemos nuestro tipo de delegado, luego declaramos una variable miembro. Esta variable miembro tiene el tipo del delegado que acabamos de crear.

MyDelegate myDelegate;

Al final de nuestro script tenemos dos métodos: PrintNum() y DoubleNum(). Podemos ver que cada uno de esos métodos tiene un retorno tipo void y toma un solo parámetro de tipo entero, al igual que nuestro delegado.

void PrintNum(int num)
{
    print("Print Num: " + num);
}

void DoubleNum(int num)
{
    print("Double Num: " + num * 2);
}

Adicionalmente, cada uno de esos métodos hace algo un poco diferente con los datos de tipo entero que se pasan. Es hora de ver exactamente qué es lo que hacen los delegados.

En el método Start(), puedes ver que le asignamos el nombre de nuestro método PrintNum() a la variable myDelegate(). Luego usamos la variable myDelegate como si fuera una función y pasamos un valor de 50.

myDelegate = PrintNum;
myDelegate(50);

Luego le asignamos el nombre del método DoubleNum a la variable myDelegate(). Una vez más, la invocamos al igual que una función.

myDelegate = DoubleNum;
myDelegate(50);

De regreso en Unity, podemos iniciar la escena y ver la vista Console.

Podemos ver que podemos invocar dos métodos diferentes usando la misma variable delegada. Esto nos proporciona mucho poder para controlar qué funciones se invocan en nuestro juego de manera dinámica.

img

Los delegados también tienen la habilidad de tener multidifusión. La difusión múltiple permite que una variable delegada simple pueda representar métodos múltiples al mismo tiempo.

Aquí tenemos una escena con una esfera. La esfera tiene un script llamado MulticastScript anexado.

En nuestro MulticastScript, podemos ver que hemos creado un patrón de delegados. Este patrón define un delegados llamado MultiDelegate().

delegate void MultiDelegate();

El mismo que no toma ningún parámetro y tiene un retorno tipo void.

MultiDelegate myMultiDelegate;

Al final de nuestro script tenemos dos métodos llamados PowerUp() y TurnRed(). Ambos métodos no toman ningún parámetro y tiene un retorno de tipo void, al igual que el tipo de nuestro delegados.

Al final de nuestro script tenemos dos métodos llamados PowerUp() y TurnRed(). Ambos métodos no toman ningún parámetro y tiene un retorno de tipo void, al igual que el tipo de nuestro delegados.

void PowerUp()
{
    print("Orb is powering up!");
}

void TurnRed()
{
    _renderer.material.color = Color.red;
}

El método PowerUp() muestra Orb is powering up en la pantalla. El método TurnRed() cambia el color del objeto a rojo.

En el método Start(), vamos a hacer una multidifusión de nuestra variable delegada. Lo hacemos asignándole ambos, el método PowerUp() y el método TurnRed(), a la misma variable delegada usando el operador +=.

De esta manera, la variable myMultiDelegate contiene ambos el método PowerUp() y el método TurnRed(). Luego invocamos la variable myMultiDelegate() como si fuera una función.

void Start()
{
    myMultiDelegate += PowerUp;
    myMultiDelegate += TurnRed;

    if(myMultiDelegate != null)
    {
        myMultiDelegate();
    }
}

Si regresamos a Unity e iniciamos nuestra escena, podemos ver que hacer una multidifusión de nuestra variable delegada le permite invocar ambos métodos, PowerUp y TurnRed con una sola invocación.

gif

De esta manera, pudimos agregarle funcionalidad. Si queremos eliminar un método de una variable delegada, podemos hacerlo usando el operador -= en conjunto con el nombre del método.

myMultiDelegate -= PowerUp;
myMultiDelegate -= TurnRed;

Una cosa con la que debemos tener cuidado es intentar invocar una variable delegada como una función antes de que le hayamos asignado algo. Esto causará un error y deberíamos evitarlos.

Cualquier variable delegada que no tiene un método asignado actualmente, tendrá un valor de null. Por lo tanto, es una buena idea siempre verificar para asegurarte que el delegado no sea igual a null antes de usarlo.

Gist del proyecto

Apoya el contenido de mi blog a través de:

Fuente:

Copiado!