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.
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.
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.
Apoya el contenido de mi blog a través de:
Fuente: