Creo que la respuesta es NO? Si no existe, ¿por qué hemos separado las clases Delegate
y MulticastDelegate
? Tal vez sea de nuevo debido a "algunos otros lenguajes .NET"?¿Hay un delegado que no sea un delegado de multidifusión en C#?
Respuesta
EDIT: I pensamiento esto era parte de ECMA 335, pero no puedo verlo allí en ninguna parte.
no se puede crear un tipo como delegado en C#, pero se puede en IL:
.class public auto ansi sealed Foo
extends [mscorlib]System.Delegate
{
// Body as normal
}
El compilador de C# no tiene problemas utilizando un delegado como:
using System;
class Test
{
static void Main()
{
Foo f = x => Console.WriteLine(x);
f("hello");
}
}
Pero el CLR hace cuando intenta cargarlo:
Excepción no controlada: System.TypeLoadException: No se pudo cargar el tipo 'Foo' desde el ensamblado 'Foo, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null 'porque no puede heredar directamente de la clase de delegado. en Test.Main()
Básicamente, la separación Delegate/MulticastDelegate es un accidente histórico. Creo que las primeras versiones alpha/beta hicieron la distinción, pero resultó ser demasiado confusa y generalmente no útil, por lo que ahora cada delegado se deriva de MulticastDelegate.
(Curiosamente, el # especificación C sólo menciona MulticastDelegate una vez, en la lista de tipos que no se pueden utilizar como limitaciones genéricos.)
No, el CLR no permite eso.
Recuerdo algo que querían exponer Delegate
directamente, pero eso nunca fue necesario.
No, no lo hay, porque todos los delegados deben poder, naturalmente, ser Delegate.Combine
ed. El delegado está allí simplemente para ajustar la funcionalidad de no multidifusión en una clase base.
Incluso si cada delegado tuviera un único puntero de método y destino, Delegate.Combine podría implementarse muy bien: simplemente cree un objeto con dos campos del tipo de delegado apropiado, que los ejecute secuencialmente. Usar MulticastDelegates puede ofrecer una ventaja de rendimiento en situaciones en las que los delegados con una gran cantidad de subdelegados se ejecutan con frecuencia, pero rara vez participan en Combinar y Eliminar, pero me sorprendería que ofrezca un mejor rendimiento en situaciones más típicas. Personalmente, me gustaría que hubiese habido un tipo mutable de "lista de eventos", quizás una estructura con un solo campo ... – supercat
... de tipo Object, que podría contener un nulo, un delegado o una matriz de delegados. , y que incluía un método para invocar ese campo, según corresponda, así como para realizar operaciones Add y Remove para la seguridad de subprocesos (utilizando Interlocked.CompareExchange); los métodos de invocación deben ofrecer la opción de detenerse en la primera excepción, o dejar que todos los controladores se ejecuten y arrojen una BundledException con una lista de todas las excepciones que se produjeron al ejecutarlas. Tener la lista de eventos para mantener las referencias de los delegados, en lugar de una lista de métodos y objetivos eliminaría las peculiaridades en el enfoque existente. – supercat
System.MuticastDelegate se deriva de System.Delegate. Cada nivel dentro de la jerarquía de delegados proporciona un conjunto diferente de servicios. System.Delegate es un contenedor de los datos de qué método llamar a un objeto en particular. Con System.MulticastDelegate viene la capacidad adicional de invocar un método en un solo objeto, pero en una colección de objetos. Esto permite múltiples suscriptores a un evento.
No estoy seguro, he respondido a tu pregunta.
Aunque eso suena apropiado, no explica por qué GetInvocationList (claramente acerca de invocar * métodos * múltiples) es parte de Delegate, y no de MulticastDelegate ... –
- 1. delegado simple (delegado) frente a delegados de multidifusión
- 2. ¿Puedo revertir el orden de un evento delegado de multidifusión?
- 3. Alcance de un delegado en C#
- 4. ¿Hay un delegado disponible para las propiedades en C#?
- 5. ¿hay un método delegado uipickerview como scrollviewDidScroll?
- 6. Cómo convertir un delegado a un delegado idéntico?
- 7. ¿Qué es un delegado de C++?
- 8. Delegado predeterminado en C#
- 9. Delegado en C++ 11
- 10. C# - ¿Cómo puedo "sobrecargar" a un delegado?
- 11. ¿Qué señala un delegado?
- 12. patrón Delegado vs palabra clave delegado en C#
- 13. Invocar un delegado en un hilo específico C#
- 14. __unsafe_unretained por un delegado no construirá
- 15. Cuándo usar (o no usar) un delegado
- 16. Expresión Lambda que devuelve un delegado
- 17. C# Delegado de propiedad?
- 18. Varios UIAlertViews para un delegado
- 19. cómo extender un protocolo para un delegado en el objetivo C, luego subclase un objeto para requerir un delegado conforme
- 20. ¿Debo anclar un delegado anónimo?
- 21. delegado C# no funciona como debería?
- 22. C#: delegado de acción frente a delegado explícito
- 23. delegado para un objeto singleton
- 24. Iniciar un nuevo proceso que ejecuta un delegado
- 25. Asignación de un método IronPython a un C# delegado
- 26. ¿Cómo declaras un delegado predicado en línea?
- 27. C# genéricos no permitirá Delegado Tipo Restricciones
- 28. Delegado de UISplitViewController en un singleton
- 29. Compruebe si un objeto es un delegado
- 30. Disparar un evento en C# sin métodos de delegado adjuntos?
¿Qué dice PEVerify en ese ensamblaje con 'Foo'? – leppie
@leppie: No lo he intentado todavía. Siéntase libre de hacerlo :) (Acabo de ejecutar ildasm en una declaración "normal" para obtener el IL, luego lo adulteré y lo reinscribí). –
Utilicé ilasm/ildasm con un delegado de prueba y obtuve el resultado esperado en su respuesta . Gracias. –