J'ai un assembly avec une classe qui définit un événement personnalisé en utilisant un délégué et des arguments d'événement personnalisés. Maintenant, je dois charger cette assembly dynamiquement à travers mon code et créer l'instance de cette classe. Jusqu'à ici je vais bien. Maintenant, je dois fournir un gestionnaire d'événement à l'événement déclenché par l'objet de classe en utilisant un délégué personnalisé. Comment puis-je ajouter un gestionnaire d'événements à l'événement déclenché à partir de la classe en utilisant Relection?C# Délégations et événements
Répondre
Je devais faire cela avant, était une vraie douleur - finalement rencontré tutorial.
Serait-il possible d'avoir une interface dans un autre assemblage que vous pourriez utiliser pour raccorder l'événement avec la réflexion? Juste une pensée ...
Un événement est un délégué multidiffusion, vous devez récupérer cet événement en tant que type de System.Delegate utilisez Delegate.Combine pour combiner les deux instances, puis définissez le délégué sur le délégué combiné.
C# a une belle syntaxe abrégée pour cela:
class SomeClass
{
public event Action<string> TextEvent;
}
Vous écrire quelque chose comme ceci: (je me sens un peu paresseux et ne vérifiera pas cela, vous devrez délier les jambes vous)
var obj = // instance of SomeClass...
var t = typeof(SomeClass); // you need the type object
var member = t.GetEvent("TextEvent");
member.AddEventHandler(obj, new Action<string>(delegate(string s)){}); // done!
Voici le code pour le faire:
class Program
{
static void Main(string[] args)
{
// Create publisher.
var pub = Activator.CreateInstance(typeof(Publisher));
// Get the event.
var addEvent = typeof(Publisher).GetEvent("Event");
// Create subscriber.
var sub = Activator.CreateInstance(typeof(Subscriber));
// Get the method.
var handler = typeof(Subscriber).GetMethod("Handle");
// Create a valid delegate for it.
var handlerDelegate = MakeEventHandlerDelegate(handler, sub);
// Add the event.
addEvent.AddEventHandler(pub, handlerDelegate);
// Call the raise method.
var raise = typeof(Publisher).GetMethod("Raise");
raise.Invoke(pub, new object[] { "Test Value" });
Console.ReadLine();
}
static Delegate MakeEventHandlerDelegate(MethodInfo methodInfo, object target)
{
ParameterInfo[] info = methodInfo.GetParameters();
if (info.Length != 2)
throw new ArgumentOutOfRangeException("methodInfo");
if (!typeof(EventArgs).IsAssignableFrom(info[1].ParameterType))
throw new ArgumentOutOfRangeException("methodInfo");
if (info[0].ParameterType != typeof(object))
throw new ArgumentOutOfRangeException("methodInfo");
return Delegate.CreateDelegate(typeof(EventHandler<>).MakeGenericType(info[1].ParameterType), target, methodInfo);
}
}
class Args : EventArgs
{
public string Value { get; set; }
}
class Publisher
{
public event EventHandler<Args> Event;
public void Raise(string value)
{
if (Event != null)
{
Args a = new Args { Value = value };
Event(this, a);
}
}
}
class Subscriber
{
public void Handle(object sender, Args args)
{
Console.WriteLine("Handle called with {0}.", args.Value);
}
}
Je suis probablement manque quelque chose, mais si vous connaissez le nom d'un signature de l'événement auquel vous devez vous connecter, vous connaissez probablement le type qui expose cet événement. Dans ce cas, pourquoi auriez-vous besoin d'utiliser la réflexion? Tant que vous avez une référence correctement typée, vous pouvez attacher un gestionnaire de la manière normale.
- 1. C# - Événements et Interfaces
- 2. Événements COM + avec C# et .NET
- 3. Événements de composant C#?
- 4. Événements de clavier C++ Win32
- 5. Comment écrire des événements et des eventhandlers en C#?
- 6. Aide à la conception de délégués et événements C#
- 7. événements jQuery et Prototype
- 8. VB6 Implémentations et événements
- 9. IoC et les événements
- 10. Délégués et événements
- 11. sIFR et javascript événements
- 12. Transférer des événements en C#
- 13. C# Gérer les événements Windows
- 14. Gestion des événements filetés (C#)
- 15. Événements de minuterie et d'animation qui troncent les événements TouchesEnded
- 16. jQuery Fermetures, boucles et événements
- 17. Délégués et événements dans Interface?
- 18. Événements DOM et élément cible
- 19. Iterop Forms Toolkit validation et focus événements
- 20. C# Événements d'alimentation CA connectés/déconnectés
- 21. décrochement événements avec lambdas en C#
- 22. Les événements d'incendie sélectivement en C#
- 23. Quand utiliser les événements C# personnalisés
- 24. capturer des événements javascript dans C#
- 25. C# winforms menu contextuel événements problème
- 26. La contravariance des événements et des délégués dans .NET 4.0 et C# 4.0
- 27. Délégués et événements de l'API VB.NET
- 28. ASP.Net ListView et la gestion des événements
- 29. Événements routés WPF, tunneling et bullage
- 30. NSRunloops et forcer le traitement des événements
Cela ne fonctionnera pas. Un événement est autant un champ qu'une propriété est un champ. Les événements ont des méthodes add_ et remove_ (que vous définissez comme get/set de la propriété, sauf que vous utilisez add/remove). –
J'ai révisé la réponse, et cela fonctionnera sûrement. –