c# - Compile-time information lost with conversion to object, cannot cast to generic interface<T> -
i have class implementing concrete typed version of generic interface. have found if pass object in function (even though might correct object) @ compile time still considered object , failing @ runtime error:
unable cast object of type 'testeventhandler' type 'idomaineventhandler '1[system.object]'.
i deserializing messages bus (which products objects, should have associated domaineventhandler<of_deserialized_type>
associated message.
in summary, problem believe idomaineventhandler<t>
not casting `idomaineventhandler<object>
, appreciate guidance on how best solve issue , still maintain generic idomaineventhandler<t>
interface objects being passed in publish()
.
[testclass] public class internalmessagehandlertests { class testevent { } class testeventhandler : idomaineventhandler<testevent> { public void handleevent(testevent domainevent) { } } [testmethod] public void test() { testevent testevent = new testevent(); object testeventasobject = testevent; // compile time type information lost publish(testevent); // ok :) publish(testeventasobject); // fails :( } public void publish<t>(t eventtopublish) t : class { var handlerinstance = new testeventhandler(); idomaineventhandler<t> converted = (idomaineventhandler<t>)handlerinstance; converted.handleevent(eventtopublish); } }
in situation, not possible support fully-generic interface without reflection. , reflection pretty bad idea such simple case.
my normal approach these situations idomaineventhandler
, domaineventhandlerbase<t> : idomaineventhandler
inheriting classes advantage of generics, outside interface can accept objects.
obviously not statically safe, said not possible statically safe here. assigned instance object testeventasobject
, made possible variable contain compiler point of view (string
, int
, anything).
for things service bus have select right handler, this:
public interface idomaineventhandler { void handleevent(object domainevent); bool canhandleevent(object domainevent); } public abstract class domaineventhandlerbase<t> : idomaineventhandler { public abstract void handleevent(t domainevent); public abstract bool canhandleevent(t domainevent); void idomaineventhandler.handleevent(object domainevent) { return handleevent((t)domainevent); } bool idomaineventhandler.canhandleevent(object domainevent) { return (domainevent t) && canhandleevent((t)domainevent); } }
i has written directly (without checking in vs) mistakes possible.
after when receive message select
handlers.first(h => h.canhandleevent(domainevent))
Comments
Post a Comment