1

Base class:

Public MustInherit Class Connector

    Public Event Changed as EventHandler

End Class

Interface:

Public Interface IPlug

    Event Changed as EventHandler

End Interface

Derived class:

Public Class OutputConnector
    Inherits Connector
    Implements IPlug

    Event Changed as EventHandler Implements IPlug.Changed

End Class

VB.Net Problem:

The Changed event in OutputConnector conflicts with the Changed event in Connector, of course. But I have to implement it to satisfy the IPlug interface.

How can I solve this?

I have other classes deriving from Connector (e.g. an InputConnector class) that need to have the Changed event, but NOT implement IPlug. And I don't want derived classes that are implementing IPlug to have an additional event just to avoid the name conflict (which would be the case if I changed the name of the event in either the base class or the interface).

Any suggestions?

Edit:

The problem is not the names per se, but that I want the derived class to somehow map its interface event implementation to the existing event in the base class - and not have to declare an additional event in the derived class (with all sorts of routing clutter to boot); after all, the event already exists in the base class! What I need is a way to let the interface know that..

A pseudo-solution (just to illustrate) would be to be able to put something to the effect of

Public Event MyBase.Changed Implements IPlug.Changed

in the derived OutputConnector class.

d7samurai
  • 3,086
  • 2
  • 30
  • 43
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Feb 12 '13 at 03:47

1 Answers1

0

This question points out two ways to make an interface implementation explicit.

  • Make it private
  • Use the fact that the name of the implementation need not match the interface name.

So it depends on how you plan on using IPlug.Changed. If you will always be using the interface to interact, then you can simply make it private, and even if it requires Shadows it won't be visible via the public API.

The other way is to decide a new name for the declaration, such as OutputConnector.IPlugChanged.

Which you select depends on how you are using everything.

EDIT:

You seem to want the two events to be identical in functionality.

In that case the best thing to do would be to hide the IPlug.Changed implementation by making it private with a different name.

Once you have hidden IPlug.Changed, use your OnChange protected method (assuming you made one) to link up the two, calling IPlugChanged when OnChange is triggered.

If you don't have an OnChange protected method, you can attach an event that performs the above call instead. Note that if you are worried about the order events are called in, this won't work.

A final option may be to use the Custom syntax to stream changes to IPlug to the base class.

Community
  • 1
  • 1
Guvante
  • 18,775
  • 1
  • 33
  • 64
  • None of these addresses my problem. The problem is not the names per se, but that I want the interface implementation in the derived class to attribute the event implementation to the event in the base class - and not have to declare an "extra" event in the derived class (the event already exists in the base class - I need a way to let the interface know that). – d7samurai Feb 12 '13 at 03:56
  • @d7samurai: I added some examples of work arounds, but it is important to note that since `OutputConnector` implements `IPlug` it is responsible for the implementation, there is no way to defer to parent (although VB.Net theoretically could provide an ease of use syntax). Although I would question whether a base interface that both implement (say `IChangeable`) might work if you have full control of both definitions. – Guvante Feb 12 '13 at 04:07
  • Yes [I want them to be identical in functionality]. In fact, they are supposed to be one and the same event and I shouldn't have to declare anything in the derived class, but rather be able to map the existing base class event to the interface implementation (in the derived class). The last thing I want is an extra event - private or not. In other words, declaring an event specifically for the IPlug implementation (with all the clutter it brings) is out of the question. That is even uglier than using Shadows.. – d7samurai Feb 12 '13 at 04:14
  • I simplified in my example. The Changed event belongs to a common ancestor (to a large hierarchy of classes), several parent classes up the tree. In other words, moving the Changed event down one level (i.e. not declaring it in Connector, but rather directly in the derived classes individually) is not an option. I think I'll stick with the Shadows for now (until VB introduces a way of doing this natively).. – d7samurai Feb 12 '13 at 04:18
  • @d7samurai: `Shadows` doesn't work, you create two events that likely won't both be called in every case. You could fudge a virtual event using [this pattern](http://stackoverflow.com/questions/715042/does-vb-net-support-virtual-events) which would probably allow you to do what you need to do with minimal syntax (still have a duplicate declaration, but it would be a minor one). – Guvante Feb 12 '13 at 04:21
  • @d7samurai: If you use shadows and someone adds an event to an `OutputConnector` directly or as an `IPlug`, they are adding it to `OutputConnector`'s implementation. If they add it as a `Connector` they add it as `Connector`'s implementation. The two need to be called distinctly or else it won't work. For instance any time `Connector` calls it, the `OutputConnector` version isn't called (unless you somehow explicitly hook it up), because it is a different event. – Guvante Feb 12 '13 at 15:31
  • 1
    Ah. Now I see what you mean.. If I `Dim c as Connector = New OutputConnector`, `c.Changed` will never be raised because that's a different event than the shadowing one raised inside the actual `OutputConnector`. So I'd have to cast `c` to an `OutputConnector` before hooking up the `Changed` event handler. But if `Event` supported `Overridable` / `Overrides` this wouldn't be a problem. Right? In any case, after our exchange last night (I'm in Europe), I revised the architecture to eliminate the problem altogether. Thanks for your input. – d7samurai Feb 12 '13 at 18:30