concepto de delegate

03/10/2005 - 22:45 por lucho | Informe spam
Gente:

¿Cual es el concepto de : delegate?

Preguntas similare

Leer las respuestas

#1 Eduardo A. Morcillo [MS MVP VB]
04/10/2005 - 05:19 | Informe spam
Un "Delegate" declara el prototipo de una funcion.
Un prototipo determina cuales son los argumentos que dicha funcion
recibe y la clase de valor que devuelve.



En mi opinion, mas que ser una especie de prototipo es un apuntador a
funcion "seguro". Por seguro se entiende a que especifica cantidad y tipos
de los parametros y su valor de retorno (si lo hay).

El valor practico:



Yo diria que el valor practico mas comun son los eventos. En VB.NET esto
queda medio oculto ya que al declarar un Event con la sintaxis de VB6 el
compilador crea un delegado para el evento.

Otra cosa a tener en cuenta con los delegados es que no son intercambiables,
es decir, si tienes definidos dos delegados con los mismos parametros y
valor de retorno no puedes asignar una instancia de uno a otro. Por ejemplo:

Delegate Sub Abc1(ByVal s As String)
Delegate Sub Abc2(ByVal s As String)

Dim test As Abc1

test = New Abc2(AddressOf x) ' Error

Pese a que los dos delegados tienen la misma definicion cada uno es
diferente. Esto no es muy notorio en VB ya que puede evitarse crear
explicitamente el delegado (con AddressOf basta para que el compilador cree
el delegado correspondiente, siempre que pueda) pero en C# si debe crearse
en forma explicita.

Otra particularidad es que a diferencia de un apuntador a funcion de C, un
delegado puede contener referencias a mas de una funcion al mismo tiempo
(esta es la propiedad que se aprovecha para eventos). Ejemplo:

Delegate Sub Abc(ByVal s As String)

Dim test As Abc

' Creo una instancia que apunte al metodo Metodo1
' Notar que no hace falta New Abc().
test = AddressOf Metodo1

' Creo una instancia que apunte al metodo Metodo2
' y la combino con la instancia anterior.
' Notar que hay que crear explicitamente el delegado.
test = [Delegate].Combine(test, New Abc(AddressOf Metodo2))

' Invoco el delegado, este llamara a Metodo1 y Metodo2
test("hola")

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo
http://mvp.support.microsoft.com/pr...4EF5A4191C
Respuesta Responder a este mensaje
#2 Leonardo Azpurua [mvp vb]
04/10/2005 - 07:42 | Informe spam
"Eduardo A. Morcillo [MS MVP VB]" <emorcillo .AT. mvps.org> escribió en el
mensaje news:u%
Un "Delegate" declara el prototipo de una funcion.
Un prototipo determina cuales son los argumentos que dicha funcion
recibe y la clase de valor que devuelve.



En mi opinion, mas que ser una especie de prototipo es un apuntador a
funcion "seguro". Por seguro se entiende a que especifica cantidad y tipos
de los parametros y su valor de retorno (si lo hay).



Hola.

Igual es cuestion de conceptos.

Un "Delegate" es la declaracion de un tipo.
Una función que cumple con la declaracion del Delegate es simplemente una
función "compatible".
Un apuntador a una función compatible con la declaracion de un Delegate
(creado por el operador AddressOf), es un apuntador "seguro" a una función.

Yo diria que el valor practico mas comun son los eventos. En VB.NET esto
queda medio oculto ya que al declarar un Event con la sintaxis de VB6 el
compilador crea un delegado para el evento.



Por eso me parece que ese no es su mayor valor practico para el usuario del
lenguaje. El uso de delegados dentro del marco conceptual de VB es
"transparente" para el programador.

Encuentro que es mucho más importante su uso potencial como mecanismo de
extensibilidad.

Salud!
Respuesta Responder a este mensaje
#3 Eduardo A. Morcillo [MS MVP VB]
04/10/2005 - 09:15 | Informe spam
Un apuntador a una función compatible con la declaracion de un
Delegate (creado por el operador AddressOf), es un apuntador "seguro"
a una función.



El problema es que AddressOf crea una instancia del delegado y no un
apuntador. La declaracion Delegate lo que hace es crear una clase derivada
de MulticastDelegate. AddressOf ya no tiene el mismo significado que tenia
en VB6. En VB.NET el compilador convierte AddressOf en un constructor del
delegado apropiado (si puede):

delegado = AddressOf MiMetodo

El compilador genera codigo equivalente a:

delegado = New MiDelegado(AddressOf MiMetodo)

El AddressOf dentro del constructor tampoco devuelve un apuntador sino que
esta solo por diferenciar el metodo de una variablereferencia a la funcion y
llamado a la funcion que obtener el apuntador. Esto lo notas si ves como es
el constructor real de la clase generada por la declaracion del delegado,
que tiene en realidad dos parametros.

Encuentro que es mucho más importante su uso potencial como mecanismo
de extensibilidad.



Probablemente, debe ser que el tipo de problema que explicaste en el otro
mensaje yo lo resuelvo con interfaces. Y asi esta resuelto tambien en la
mayor parte del framework donde los delegados se usan para eventos y
callbacks pero no para pasar extender la funcionalidad del metodo que se
esta llamando (hay algunas pocas excepciones como ThreadStart).

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo
http://mvp.support.microsoft.com/pr...4EF5A4191C
Respuesta Responder a este mensaje
#4 Leonardo Azpurua [mvp vb]
04/10/2005 - 10:24 | Informe spam
"Eduardo A. Morcillo [MS MVP VB]" <emorcillo .AT. mvps.org> escribió en el
mensaje news:
El problema es que AddressOf crea una instancia del delegado y no un
apuntador. La declaracion Delegate lo que hace es crear una clase derivada
de MulticastDelegate. AddressOf ya no tiene el mismo significado que tenia
en VB6. En VB.NET el compilador convierte AddressOf en un constructor del
delegado apropiado (si puede):

delegado = AddressOf MiMetodo

El compilador genera codigo equivalente a:

delegado = New MiDelegado(AddressOf MiMetodo)

El AddressOf dentro del constructor tampoco devuelve un apuntador sino que
esta solo por diferenciar el metodo de una variablereferencia a la funcion
y llamado a la funcion que obtener el apuntador. Esto lo notas si ves como
es el constructor real de la clase generada por la declaracion del
delegado, que tiene en realidad dos parametros.



Bueno. Imagino que me tocará "ildasmar" (¿que tal?) una aplicacion de
consola con delegados para no darte la razón como a los locos :)

Encuentro que es mucho más importante su uso potencial como mecanismo
de extensibilidad.



Probablemente, debe ser que el tipo de problema que explicaste en el otro
mensaje yo lo resuelvo con interfaces. Y asi esta resuelto tambien en la
mayor parte del framework donde los delegados se usan para eventos y
callbacks pero no para pasar extender la funcionalidad del metodo que se
esta llamando (hay algunas pocas excepciones como ThreadStart).



Si al final los Delegados son clases despachadoras de métodos, imagino que
da igual usar una interfaz que un delegado.

En cualquier caso, me parece más directo -y mas flexible- utilizar un
delegado para una función que implementar una interfaz.

Mas flexible porque imagino que usando interfaces escribiras:

Public Interface IProcesadorPagoFactura
Sub ProcesarPago(laFactura As Factura)
End Interface

Y...

Public Class ControladorFacturas
Public Sub ProcesarFactura(laFactura As Factura, ProcesadorPago As
IProcesadorPago)
...
ProcesadorPago.ProcesarPago(laFactura)
...
End Sub

y en el nivel mas alto de la aplicacion (mejor inmediatamente "debajo" de
la forma de captura, o incluso desde la forma misma):

If Condicion = cndCredito Then
Procesador.Procesar laFactura, New ProcesadorPagoCredito
Else
Procesador.Procesar laFactura, New ProcesadorPagoContado
End If

(donde ProcesadorPagoXxx... implementa IProcesadorPagoFactura).

Si IProcesadorPagoFactura pudiera tener varias funciones utilizables desde
ControladorFacturas.ProcesarFactura (por limitarnos al ejemplo), puede tener
sentido el uso de una Interfaz en vez de un Delegate. A cambio de ello
pierdes la posibilidad de declarar en ese "nivel mas alto de la aplicacion",
algo asi como:

Public Sub ProcesarFacturaContado(laFactura As Factura) ...
y
Public Sub ProcesarFacturaCredito(laFactura As Factura) ...

y cambiar la llamada por:

If Condicion = cndCredito Then
Procesador.Procesar laFactura, AddressOf ProcesarFacturaCredito
Else
Procesador.Preocesar laFactura, AddressOf ProcesarFacturaContado
End If

en este caso (concedido que es una sobresimplificacion), el uso de Delgados
te permite una estructura mucho mas simple (no necesitas clases separadas
para implementarlos). En terminos generales, es mas rico en posibilidades el
uso de interfaces. Pero estoy seguro de que hay casos en los que usar
delegados es mas economico.

Salud!
-
Por cierto... ¿podrías explicarme como a un niño de cuatro años cual es el
equivalente de Read/Write properties en los UC de VB.NET?
Respuesta Responder a este mensaje
#5 Leonardo Azpurua [mvp vb]
04/10/2005 - 15:55 | Informe spam
"Leonardo Azpurua [mvp vb]" <l e o n a r d o (arroba) m v p s (punto) o r g>
escribió en el mensaje news:

Por cierto... ¿podrías explicarme como a un niño de cuatro años cual es el
equivalente de Read/Write properties en los UC de VB.NET?



Pregunta tonta que solo puede formularse cerca de las 4 a.m. cuando se esta
haciendo experimentos que no salen, y que se ruega a la concurrencia ignorar
<:-S
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida