Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / September 2007

Tip: Looking for answers? Try searching our database.

Replacing an event

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
MikeP - 27 Sep 2007 14:21 GMT
Hi there,

I wrote a replacement for the native .NET class "FileDialog" with my own
"FileOk" event (triggered when the user selects a file and clicks OK). Let's
say I now want to create a derivative called "MyFileDialog" and replace the
"FileOk" event with a new event called "MyFileOk". Users of this class
should therefore rely on the latter event and not "FileOk" from the base
class. Is it therefore possible to hide the base class' "FileOk" event so
that users can't invoke it. Redefining it as private doesn't help (the base
class version kicks in instead) so the only way I can see is to redefine it
as "public" (using the "new" keyword) and then throwing a
"System.NotImplementedException" (also asserting in the debug version). This
is ugly IMO however so I'm hoping there's a cleaner way. Any advice would be
appreciated. Thanks.
Jon Skeet [C# MVP] - 27 Sep 2007 16:07 GMT
> I wrote a replacement for the native .NET class "FileDialog" with my own
> "FileOk" event (triggered when the user selects a file and clicks OK). Let's
[quoted text clipped - 8 lines]
> is ugly IMO however so I'm hoping there's a cleaner way. Any advice would be
> appreciated. Thanks.

If you don't want a client to be able to use a member of the base
class, you shouldn't derive from it.

You could make it virtual, override it, and add a deprecated attribute
to it - but it's a bit horrible. You *should* be able to use an
instance of a derived class as if it were an instance of the base
class.

Jon
MikeP - 27 Sep 2007 16:33 GMT
>> I wrote a replacement for the native .NET class "FileDialog" with my own
>> "FileOk" event (triggered when the user selects a file and clicks OK).
[quoted text clipped - 22 lines]
> instance of a derived class as if it were an instance of the base
> class.

Thanks for the feedback. Actually I agree with this in principle. However,
this was a very late change so I didn't want to have to start aggregating
the base class as a private member (as one possible solution), especially
for this one minor change. Note that in C++ you have more flexibility with
this issue. You can privately derive from a base class for instance and then
publicly expose only what you want. I find this approach somewhat ugly as
well however. In any case, I'll probably stick with my original idea until
the next release since I control all clients anyway (though I might add the
obsolete attribute you suggested). Anyway, thanks again.
Doug Semler - 27 Sep 2007 16:53 GMT
> You could make it virtual, override it, and add a deprecated attribute
> to it - but it's a bit horrible. You *should* be able to use an
> instance of a derived class as if it were an instance of the base
> class.

I *expect* to be able to use a derived class as if it were an instance
of the base class. :)

I have a feeling that the derived class event wants to pass more
information to the client than the base event.  What I personally
would do is fire both events in the derived class.  Let the client
decide which event to hook to, or even both (just document that both
events would be fired).  I don't like this but it would be the
"easiest" solution...

Or you could virutalize the event, an OnEvent() method, and derive the
event args for the derived event from the base eventargs.  Then the
client can hook to the same name (regardless).  The derived class
fires the event with the derived event args, and the base class fires
the event with the base event args.  It would be up to the client to
attempt to cast the base event args structure in the event handler to
determine what fired.  I don't really like that either, it requires
the client to jump through some hoops in the event handler code....

The second case could look something like (IMO NOT "a good idea
(tm)"):
   public class BaseEventArgs : EventArgs
   {
       public string BaseInfo
       {
           get
           {
               return "Only Base Info available";
           }
       }
   }

   public class DerivedEventArgs : BaseEventArgs
   {
       public string DerivedInfo
       {
           get
           {
               return "DerivedInfoAvailable";
           }
       }
   }

   public class BaseClass
   {
       virtual public event EventHandler<BaseEventArgs> MyEvent;

       protected virtual void OnMyEvent()
       {
           EventHandler<BaseEventArgs> b = MyEvent;
           if (b != null)
               b(this, new BaseEventArgs());
       }

       internal void Fire()
       {
           OnMyEvent();
       }
   }

   public class DerivedClass : BaseClass
   {
       public override event EventHandler<BaseEventArgs> MyEvent;

       protected override void OnMyEvent()
       {
           EventHandler<BaseEventArgs> b = MyEvent;
           if (b != null)
               b(this, new DerivedEventArgs());
       }
   }

   class Program
   {
       static void Main(string[] args)
       {
           BaseClass s = new DerivedClass();
           s.MyEvent += new EventHandler<BaseEventArgs>(s_MyEvent);

           Console.WriteLine("Firing Derived Class instance");
           s.Fire();

           s = new BaseClass();
           s.MyEvent += new EventHandler<BaseEventArgs>(s_MyEvent);
           Console.WriteLine("Firing Base Class instance");
           s.Fire();
       }

       static void s_MyEvent(object sender, BaseEventArgs e)
       {
           DerivedEventArgs de = e as DerivedEventArgs;
           if (de != null)
           {
               // Do stuff with derived event args
               Console.WriteLine(de.DerivedInfo);
           }
           // Can do stuff with base event info
           Console.WriteLine(e.BaseInfo);
       }
   }

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.