Avec : Event un type générique (acceptant un EventArg) TestEvent, l'event qui est écouté, Subscriber un type héritant de IEventSubscriber onEvent une fonction de type void(TestEvent), récupérée sous la forme d'une Action<TestEvent> m_subscriberList une List<IEventSubscriber>.
Je voudrais pouvoir indiquer un nom d’événement dans l'inspector (ici "TestEvent"), et pouvoir connecter l’évent demandé dynamiquement (en vu de créer un système de tuto).
Voici ce que j'ai réalisé
Type t = Type.GetType(eventName);
if(t == null)
{
Debug.LogError("Can't find the event type " + eventName);
return;
}
Type eventType = typeof(Event<>);
var s = eventType.MakeGenericType(new Type[] { t }).GetNestedType("Subscriber");
var m = typeof(TutorialLogic).GetMethod("onEvent", BindingFlags.NonPublic | BindingFlags.Instance);
var genericM = m.MakeGenericMethod(new Type[] { t });
var action = typeof(Action<>).MakeGenericType(new Type[] { t });
m_subscriberList.Add((IEventSubscriber)s.GetConstructors()[0].Invoke(new object[] { Delegate.CreateDelegate(action, this, genericM) }));
J'obtiens l'exception suivante au runtime, à la création du subscriber (dernière ligne) :
Je trouve curieux de devoir passer par de la reflection pour faire ce genre de tâche. Je pense que tu aurais un système un peu plus robuste et performant si tu poussais l'usage des interfaces un peu plus loin.
Cela dit...Je ne suis pas certain que l'équivalent de "onEvent" soit "[...].GetMethod("onEvent", [...]).MakeGenericMethod([...])". Si "onEvent" est effectivement une méthode dont la signature est du style "void(TestEvent)", il ne s'agit aucunement d'une méthode générique. Je suis même étonné que le code ne plante pas sur "MakeGenericMethod" étant donné que tu tente de faire une liaison impossible à résoudre (spécialiser une méthode générique alors que la méthode en question n'accepte aucun argument de généricité). Le MakeGenericMethod est de trop. Tente sans ça, ça devrait mieux fonctionner plus bas. Le MakeGenericMethod aurait eu du sens si ta méthode avait été "onEvent<T>" de signature "void<T>(T)" (+ contrainte si nécessaire).
C'est une coquille qui s'est glissé dans mon text, je testais le fonctionnement de mon système avec un event de ce nom, mais sinon oui, onEvent est bien un générique (sinon je ne pourrais pas lui connecter un event d'un autre type). Je ne vois pas trop comment les interfaces me permettrais de rendre ceci plus efficace, il me faut dans tous les cas passer par l'inspector, donc récupérer un nom.
Entre temps je suis passé par une solution plus simple, mais beaucoup moins élégante, en hardcodant les events dont j'ai besoin.
Bien que je n'en ai plus besoin actuellement, je laisse le sujet ouvert, car la réponse m’intéresse.
"Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein
Reflection avec delegates & generics
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.