|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Checking that an event has handlers added to it - using ReflectionI am creating a simple class library for simplifying reflection. I am creating an EventWrapper class that allows programmers to treat it like an event (minus the operator overloading). I am concerned with how to check that handlers have been added to the event prior to raising it. For instance, if (TextChanged != null) { TextChanged(this, EventArgs.Empty); } tests whether there are any handlers prior to raising the event. How can I do this with the EventInfo class? Thanks! Basically there is no robust way of doing this... your cited code
masks a compiler trick - a hidden delegate field. EventInfo points to the accessors, not the implementation. It is (commonly) the *field* (sitting behind the accessors) that has the value, and you'd need to check that. But sometimes the field is developer-generated (with custom add/remove accessors) and sometimes there *is* no such field (perhaps using EventHandlerList). Or perhaps it does something even more esoteric - registers subscribers in a centralised class for some reason. Marc On Nov 27, 10:55 am, Marc Gravell <marc.grav***@gmail.com> wrote:
> Basically there is no robust way of doing this... your cited code It sounds like I should just let an error happen then. What would be> masks a compiler trick - a hidden delegate field. EventInfo points to > the accessors, not the implementation. > It is (commonly) the *field* (sitting behind the accessors) that has > the value, and you'd need to check that. But sometimes the field is > developer-generated (with custom add/remove accessors) and sometimes > there *is* no such field (perhaps using EventHandlerList). Or perhaps > it does something even more esoteric - registers subscribers in a > centralised class for some reason. > > Marc the benefit of masking it with a try {} catch {}. Would the hide errors that took place in the event handlers? or would it just hide that the event didn't have any listeners? > It sounds like I should just let an error happen then. What would be To be honest, I'm confused as to how you are going to (robustly) do> the benefit of masking it with a try {} catch {}. Would the hide > errors that took place in the event handlers? or would it just hide > that the event didn't have any listeners? *anything* useful (other than subscribe/unsubscribe) with an EventInfo. If you are thinking of using the GetRaiseMethod(), then note the remark on MSDN: <q>This method returns a null reference (Nothing in Visual Basic) for events declared with the C# event keyword or the Visual Basic Event keyword. This is because the C# and Visual Basic compilers do not generate such a method.</q> http://msdn2.microsoft.com/en-us/library/1a4k4e35.aspx Marc On Nov 27, 12:32 pm, Marc Gravell <marc.grav***@gmail.com> wrote:
Show quote > > It sounds like I should just let an error happen then. What would be I will have to test this. Thank you for bringing that to my attention.> > the benefit of masking it with a try {} catch {}. Would the hide > > errors that took place in the event handlers? or would it just hide > > that the event didn't have any listeners? > > To be honest, I'm confused as to how you are going to (robustly) do > *anything* useful (other than subscribe/unsubscribe) with an > EventInfo. If you are thinking of using the GetRaiseMethod(), then > note the remark on MSDN: > <q>This method returns a null reference (Nothing in Visual Basic) for > events declared with the C# event keyword or the Visual Basic Event > keyword. This is because the C# and Visual Basic compilers do not > generate such a method.</q> > > http://msdn2.microsoft.com/en-us/library/1a4k4e35.aspx > > Marc Ah . . . you are right. MSDN is right. How the heck will I be able to raise events for dynamically generated code? Maybe if you post how you expect to eventually consume the completed
EventWrapper (i.e. your use-case) we might suggest the best solution? On Nov 27, 1:02 pm, Marc Gravell <marc.grav***@gmail.com> wrote:
> Maybe if you post how you expect to eventually consume the completed On Nov 27, 1:02 pm, Marc Gravell <marc.grav***@gmail.com> wrote:> EventWrapper (i.e. your use-case) we might suggest the best solution? > Maybe if you post how you expect to eventually consume the completed Here is the gist of what I am trying to do.> EventWrapper (i.e. your use-case) we might suggest the best solution? We have lots of business objects to make for lots of projects. Right now the most time-consuming thing is the creation of the business objects, writing each of their properties, writing all their SQL and all the other gobbledy gook. I want to make a tool that allows the developer to pick columns from tables (which I have already done) and have it pull out the correct type, do string length/other data verification, and write base-line SQL. I have everything I need to do that now. I wrote a reflection class that can execute generated code. I have code that builds C# and compiles it. Now, generally, I don't intend to run the generated Assemblies, or generate them. My main intent is to create the source code, which I have already done. However, I am currently in the process of creating an XML-based format that will allow me to configure B.O.s and have the effects take place instantly without needing to recompile. The problem comes when my . . . wait a minute! Actually, now that I think about it, you can only raise an event inside a class anyway! My source code generator should be responsible for creating code for raising events, not the EventInfo class. The only thing you really should be able to do to a reflected Event *is* add or remove handlers, which my code already supports. I can't think of a good reason to allow reflection to raise events. Thank you for the verification. Now I can get this code generator to work! Thanks, you may have just helped me save my company a lot of time and money. !Travis
Show quote
On 27 Nov, 22:46, "jehugalea***@gmail.com" <jehugalea***@gmail.com> No problem, but on this occasion I'm genuinely not sure I didwrote: > On Nov 27, 1:02 pm, Marc Gravell <marc.grav***@gmail.com> wrote: > > > Maybe if you post how you expect to eventually consume the completed > > EventWrapper (i.e. your use-case) we might suggest the best solution? > > On Nov 27, 1:02 pm, Marc Gravell <marc.grav***@gmail.com> wrote: > > > Maybe if you post how you expect to eventually consume the completed > > EventWrapper (i.e. your use-case) we might suggest the best solution? > > Here is the gist of what I am trying to do. > > We have lots of business objects to make for lots of projects. Right > now the most time-consuming thing is the creation of the business > objects, writing each of their properties, writing all their SQL and > all the other gobbledy gook. > > I want to make a tool that allows the developer to pick columns from > tables (which I have already done) and have it pull out the correct > type, do string length/other data verification, and write base-line > SQL. I have everything I need to do that now. I wrote a reflection > class that can execute generated code. I have code that builds C# and > compiles it. > > Now, generally, I don't intend to run the generated Assemblies, or > generate them. My main intent is to create the source code, which I > have already done. However, I am currently in the process of creating > an XML-based format that will allow me to configure B.O.s and have the > effects take place instantly without needing to recompile. The problem > comes when my . . . wait a minute! > > Actually, now that I think about it, you can only raise an event > inside a class anyway! My source code generator should be responsible > for creating code for raising events, not the EventInfo class. The > only thing you really should be able to do to a reflected Event *is* > add or remove handlers, which my code already supports. > > I can't think of a good reason to allow reflection to raise events. > Thank you for the verification. Now I can get this code generator to > work! > > Thanks anything! For reference the common pattern is: public event SomeEventHandler SomeEvent; // optionally bespoke add/ remove protected void OnSomeEvent(...) { // args perhaps by delegate signature // code that fires SomeEvent } then you can simply find you EventInfo and then look for a MethodInfo based on On{TheName} Marc
Other interesting topics
|
|||||||||||||||||||||||