PC Review


Reply
Thread Tools Rate Thread

How do I isolate event-generating code in a derived class?

 
 
Elder Hyde
Guest
Posts: n/a
 
      17th Jan 2004
Hey all,

A class of mine needs to tell the outside world when its buffer is not
empty. The problem is that C# seems to force you to put the
event-raising code in the base class. To illustrate, consider what I'll
do in Java:

public interface DataAvailabilityListener extends java.util.EventListener {
void dataArrived(DataAvailabilityEvent event);
}

then, in my base class, I can do this:

public abstract class SmartQueue {
addDataAvailabilityListener(DataAvailabilityListener listener);
}

then in my implementation class, say a memory-backed smart queue, I can
do this:

public class MemorySmartQueue implements SmartQueue {
public void poolForData() {
// data available!
while(iter.hasNext()) {
DataAvailabilityListener lis =
(DataAvailabilityListener)iter.next();
lis.dataArrived(someEvent);
}
}
}

Simple and straighforward. However, consider a C# implementation: in the
interface, I may have something like this:

public abstract class SmartQueue {
public event DataAvailabilityEventHandler DataArrived;
}

Now, consider what I have to do in MemorySmartQueue:

public class MemorySmartQueue : SmartQueue {
public override void poolForData() {
// data available!
if(DataArrived == null) {
// BZZZZTTT!!! Can only do this in SmartQueue!
DataArrived(this, args);
}
}
}

I can't believe this. Either I'm missing a really obvious thing, or I
have to deal with this... this... awkward mechanism. Why the hell
doesn't it allow me to raise an event in the derived class? I don't want
to put any behaviour in my abstract class, I want to put just an interface!

Is there any way around this? (Plus I hope Whidbey will give us a Set
collection, dammit).

TIA!
Elder
 
Reply With Quote
 
 
 
 
Elder Hyde
Guest
Posts: n/a
 
      17th Jan 2004
Oops, please replace "implements" with "extends"

Elder Hyde wrote:

> Hey all,
>
> A class of mine needs to tell the outside world when its buffer is not
> empty. The problem is that C# seems to force you to put the
> event-raising code in the base class. To illustrate, consider what I'll
> do in Java:
>
> public interface DataAvailabilityListener extends java.util.EventListener {
> void dataArrived(DataAvailabilityEvent event);
> }
>
> then, in my base class, I can do this:
>
> public abstract class SmartQueue {
> addDataAvailabilityListener(DataAvailabilityListener listener);
> }
>
> then in my implementation class, say a memory-backed smart queue, I can
> do this:
>
> public class MemorySmartQueue implements SmartQueue {
> public void poolForData() {
> // data available!
> while(iter.hasNext()) {
> DataAvailabilityListener lis =
> (DataAvailabilityListener)iter.next();
> lis.dataArrived(someEvent);
> }
> }
> }
>
> Simple and straighforward. However, consider a C# implementation: in the
> interface, I may have something like this:
>
> public abstract class SmartQueue {
> public event DataAvailabilityEventHandler DataArrived;
> }
>
> Now, consider what I have to do in MemorySmartQueue:
>
> public class MemorySmartQueue : SmartQueue {
> public override void poolForData() {
> // data available!
> if(DataArrived == null) {
> // BZZZZTTT!!! Can only do this in SmartQueue!
> DataArrived(this, args);
> }
> }
> }
>
> I can't believe this. Either I'm missing a really obvious thing, or I
> have to deal with this... this... awkward mechanism. Why the hell
> doesn't it allow me to raise an event in the derived class? I don't want
> to put any behaviour in my abstract class, I want to put just an interface!
>
> Is there any way around this? (Plus I hope Whidbey will give us a Set
> collection, dammit).
>
> TIA!
> Elder

 
Reply With Quote
 
Chris Taylor
Guest
Posts: n/a
 
      17th Jan 2004
Hi,

It is standard to implement a method to fire the event, this method is the
event name prefixed with 'On'. So in your case the base class would have a
OnDataArrived, which can be called from anywhere. This has the advantage of
not having to cluter your code checking if the event has any delegates
before firing and also gives the derived implementation an alternative and
better performing method of handling the event by overriding the On...
method.

public abstract class SmartQueue
{
public event DataAvailabilityEventHandler DataArrived;

// This is called to fire the event
public void OnDataArrived( YourEventArgs e )
{
if ( DataArrived != null )
DataArrived( this, e );
}
}

public class MemorySmartQueue : SmartQueue
{
public override void poolForData()
{
// data available!
OnDataArrived( args ); // Fire the event
}
}


Hope this helps
--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Elder Hyde" <no_way> wrote in message
news:%(E-Mail Removed)...
> Hey all,
>
> A class of mine needs to tell the outside world when its buffer is not
> empty. The problem is that C# seems to force you to put the
> event-raising code in the base class. To illustrate, consider what I'll
> do in Java:
>
> public interface DataAvailabilityListener extends java.util.EventListener

{
> void dataArrived(DataAvailabilityEvent event);
> }
>
> then, in my base class, I can do this:
>
> public abstract class SmartQueue {
> addDataAvailabilityListener(DataAvailabilityListener listener);
> }
>
> then in my implementation class, say a memory-backed smart queue, I can
> do this:
>
> public class MemorySmartQueue implements SmartQueue {
> public void poolForData() {
> // data available!
> while(iter.hasNext()) {
> DataAvailabilityListener lis =
> (DataAvailabilityListener)iter.next();
> lis.dataArrived(someEvent);
> }
> }
> }
>
> Simple and straighforward. However, consider a C# implementation: in the
> interface, I may have something like this:
>
> public abstract class SmartQueue {
> public event DataAvailabilityEventHandler DataArrived;
> }
>
> Now, consider what I have to do in MemorySmartQueue:
>
> public class MemorySmartQueue : SmartQueue {
> public override void poolForData() {
> // data available!
> if(DataArrived == null) {
> // BZZZZTTT!!! Can only do this in SmartQueue!
> DataArrived(this, args);
> }
> }
> }
>
> I can't believe this. Either I'm missing a really obvious thing, or I
> have to deal with this... this... awkward mechanism. Why the hell
> doesn't it allow me to raise an event in the derived class? I don't want
> to put any behaviour in my abstract class, I want to put just an

interface!
>
> Is there any way around this? (Plus I hope Whidbey will give us a Set
> collection, dammit).
>
> TIA!
> Elder



 
Reply With Quote
 
Guest
Posts: n/a
 
      17th Jan 2004
How can we perform an Async event in C#?

Events are Synchronous usually. Do we just call BeginInvoke, if so, how
would we do this?

"Chris Taylor" <(E-Mail Removed)> wrote in message
news:#(E-Mail Removed)...
> Hi,
>
> It is standard to implement a method to fire the event, this method is the
> event name prefixed with 'On'. So in your case the base class would have a
> OnDataArrived, which can be called from anywhere. This has the advantage

of
> not having to cluter your code checking if the event has any delegates
> before firing and also gives the derived implementation an alternative and
> better performing method of handling the event by overriding the On...
> method.
>
> public abstract class SmartQueue
> {
> public event DataAvailabilityEventHandler DataArrived;
>
> // This is called to fire the event
> public void OnDataArrived( YourEventArgs e )
> {
> if ( DataArrived != null )
> DataArrived( this, e );
> }
> }
>
> public class MemorySmartQueue : SmartQueue
> {
> public override void poolForData()
> {
> // data available!
> OnDataArrived( args ); // Fire the event
> }
> }
>
>
> Hope this helps
> --
> Chris Taylor
> http://dotnetjunkies.com/WebLog/chris.taylor/
> "Elder Hyde" <no_way> wrote in message
> news:%(E-Mail Removed)...
> > Hey all,
> >
> > A class of mine needs to tell the outside world when its buffer is not
> > empty. The problem is that C# seems to force you to put the
> > event-raising code in the base class. To illustrate, consider what I'll
> > do in Java:
> >
> > public interface DataAvailabilityListener extends

java.util.EventListener
> {
> > void dataArrived(DataAvailabilityEvent event);
> > }
> >
> > then, in my base class, I can do this:
> >
> > public abstract class SmartQueue {
> > addDataAvailabilityListener(DataAvailabilityListener listener);
> > }
> >
> > then in my implementation class, say a memory-backed smart queue, I can
> > do this:
> >
> > public class MemorySmartQueue implements SmartQueue {
> > public void poolForData() {
> > // data available!
> > while(iter.hasNext()) {
> > DataAvailabilityListener lis =
> > (DataAvailabilityListener)iter.next();
> > lis.dataArrived(someEvent);
> > }
> > }
> > }
> >
> > Simple and straighforward. However, consider a C# implementation: in the
> > interface, I may have something like this:
> >
> > public abstract class SmartQueue {
> > public event DataAvailabilityEventHandler DataArrived;
> > }
> >
> > Now, consider what I have to do in MemorySmartQueue:
> >
> > public class MemorySmartQueue : SmartQueue {
> > public override void poolForData() {
> > // data available!
> > if(DataArrived == null) {
> > // BZZZZTTT!!! Can only do this in SmartQueue!
> > DataArrived(this, args);
> > }
> > }
> > }
> >
> > I can't believe this. Either I'm missing a really obvious thing, or I
> > have to deal with this... this... awkward mechanism. Why the hell
> > doesn't it allow me to raise an event in the derived class? I don't want
> > to put any behaviour in my abstract class, I want to put just an

> interface!
> >
> > Is there any way around this? (Plus I hope Whidbey will give us a Set
> > collection, dammit).
> >
> > TIA!
> > Elder

>
>



 
Reply With Quote
 
Elder Hyde
Guest
Posts: n/a
 
      17th Jan 2004
Hi Chris,

So there's really no way of escaping this? The thing is that I want my
abstract class to be really just an interface, with no implementation.
The way I'd like to organize it is something like:

public abstract class SmartQueue {
// all interface stuff only, plus
// static methods
}

public abstract class AbstractSmartQueue : SmartQueue {
// put stuff that are common to base classes here.
}

public class MemorySmartQueue : AbstractSmartQueue {
// put memory-backed specific operations here
}

Now, I can't (or rather don't want to) make SmartQueue an interface,
because: I want to have static methods--it makes the most sense to put
them in SmartQueue. But anyway, OK, I know the way now. Thanks!

Regards,
Elder


Chris Taylor wrote:

> Hi,
>
> It is standard to implement a method to fire the event, this method is the
> event name prefixed with 'On'. So in your case the base class would have a
> OnDataArrived, which can be called from anywhere. This has the advantage of
> not having to cluter your code checking if the event has any delegates
> before firing and also gives the derived implementation an alternative and
> better performing method of handling the event by overriding the On...
> method.
>
> public abstract class SmartQueue
> {
> public event DataAvailabilityEventHandler DataArrived;
>
> // This is called to fire the event
> public void OnDataArrived( YourEventArgs e )
> {
> if ( DataArrived != null )
> DataArrived( this, e );
> }
> }
>
> public class MemorySmartQueue : SmartQueue
> {
> public override void poolForData()
> {
> // data available!
> OnDataArrived( args ); // Fire the event
> }
> }
>
>
> Hope this helps

 
Reply With Quote
 
Chris Taylor
Guest
Posts: n/a
 
      17th Jan 2004
Hi,

Mistake in my code, in my haste, I forgot to make the On.... virtual SORRY.

public virtual void OnDataArrived( YourEventArgs e )

Regards

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
"Chris Taylor" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> Hi,
>
> It is standard to implement a method to fire the event, this method is the
> event name prefixed with 'On'. So in your case the base class would have a
> OnDataArrived, which can be called from anywhere. This has the advantage

of
> not having to cluter your code checking if the event has any delegates
> before firing and also gives the derived implementation an alternative and
> better performing method of handling the event by overriding the On...
> method.
>
> public abstract class SmartQueue
> {
> public event DataAvailabilityEventHandler DataArrived;
>
> // This is called to fire the event
> public void OnDataArrived( YourEventArgs e )
> {
> if ( DataArrived != null )
> DataArrived( this, e );
> }
> }
>
> public class MemorySmartQueue : SmartQueue
> {
> public override void poolForData()
> {
> // data available!
> OnDataArrived( args ); // Fire the event
> }
> }
>
>
> Hope this helps
> --
> Chris Taylor
> http://dotnetjunkies.com/WebLog/chris.taylor/
> "Elder Hyde" <no_way> wrote in message
> news:%(E-Mail Removed)...
> > Hey all,
> >
> > A class of mine needs to tell the outside world when its buffer is not
> > empty. The problem is that C# seems to force you to put the
> > event-raising code in the base class. To illustrate, consider what I'll
> > do in Java:
> >
> > public interface DataAvailabilityListener extends

java.util.EventListener
> {
> > void dataArrived(DataAvailabilityEvent event);
> > }
> >
> > then, in my base class, I can do this:
> >
> > public abstract class SmartQueue {
> > addDataAvailabilityListener(DataAvailabilityListener listener);
> > }
> >
> > then in my implementation class, say a memory-backed smart queue, I can
> > do this:
> >
> > public class MemorySmartQueue implements SmartQueue {
> > public void poolForData() {
> > // data available!
> > while(iter.hasNext()) {
> > DataAvailabilityListener lis =
> > (DataAvailabilityListener)iter.next();
> > lis.dataArrived(someEvent);
> > }
> > }
> > }
> >
> > Simple and straighforward. However, consider a C# implementation: in the
> > interface, I may have something like this:
> >
> > public abstract class SmartQueue {
> > public event DataAvailabilityEventHandler DataArrived;
> > }
> >
> > Now, consider what I have to do in MemorySmartQueue:
> >
> > public class MemorySmartQueue : SmartQueue {
> > public override void poolForData() {
> > // data available!
> > if(DataArrived == null) {
> > // BZZZZTTT!!! Can only do this in SmartQueue!
> > DataArrived(this, args);
> > }
> > }
> > }
> >
> > I can't believe this. Either I'm missing a really obvious thing, or I
> > have to deal with this... this... awkward mechanism. Why the hell
> > doesn't it allow me to raise an event in the derived class? I don't want
> > to put any behaviour in my abstract class, I want to put just an

> interface!
> >
> > Is there any way around this? (Plus I hope Whidbey will give us a Set
> > collection, dammit).
> >
> > TIA!
> > Elder

>
>



 
Reply With Quote
 
Elder Hyde
Guest
Posts: n/a
 
      17th Jan 2004
Happened to me all the time.. I hadn't been typing "virtual" for about 7
years, since I left C++ behind

Chris Taylor wrote:

> Hi,
>
> Mistake in my code, in my haste, I forgot to make the On.... virtual SORRY.
>
> public virtual void OnDataArrived( YourEventArgs e )
>
> Regards
>

 
Reply With Quote
 
Chris Taylor
Guest
Posts: n/a
 
      17th Jan 2004
Hi,

You could use BeginInvoke, and remember to always call EndInvoke. The events
will still be fired synchroneously, but in a separate thread. Something like
the following should do, this will be limited to only one handler however.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
DataArrived.BeginInvoke( this, e, new AsyncCallback(
DataArrivedCompleted ), null );
}

private void DataArrivedCompleted( IAsyncResult ar )
{
if ( DataArrived != null )
DataArrived.EndInvoke( ar );
}

You could also just use a separate thread to fire the event in, that way you
can have multiple handlers.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
System.Threading.ThreadPool.QueueUserWorkItem( new
System.Threading.WaitCallback( FireDataArrived ), e );
}

private void FireDataArrived( object e )
{
if ( DataArrived != null )
DataArrived( this, (EventArgs)e );
}

Then you can also fire each handler individually.

public virtual void OnDataArrived( EventArgs e )
{
if ( DataArrived != null )
foreach( DataAvailabilityEventHandler d in
DataArrived.GetInvocationList() )
{
d.BeginInvoke( this, e, new AsyncCallback(DataArrivedEventComplete),
d );
}
}

private void DataArrivedEventComplete( IAsyncResult ar )
{
DataAvailabilityEventHandler e =
(DataAvailabilityEventHandler)ar.AsyncState;
e.EndInvoke( ar );
}

Of course you would have to make sure the caller is aware of this
non-standard event calling and manage thread syncronization for shared data
etc. This code also lacks significant error handling, but should leave you
with a number of options.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/WebLog/chris.taylor/
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> How can we perform an Async event in C#?
>
> Events are Synchronous usually. Do we just call BeginInvoke, if so, how
> would we do this?
>
> "Chris Taylor" <(E-Mail Removed)> wrote in message
> news:#(E-Mail Removed)...
> > Hi,
> >
> > It is standard to implement a method to fire the event, this method is

the
> > event name prefixed with 'On'. So in your case the base class would have

a
> > OnDataArrived, which can be called from anywhere. This has the advantage

> of
> > not having to cluter your code checking if the event has any delegates
> > before firing and also gives the derived implementation an alternative

and
> > better performing method of handling the event by overriding the On...
> > method.
> >
> > public abstract class SmartQueue
> > {
> > public event DataAvailabilityEventHandler DataArrived;
> >
> > // This is called to fire the event
> > public void OnDataArrived( YourEventArgs e )
> > {
> > if ( DataArrived != null )
> > DataArrived( this, e );
> > }
> > }
> >
> > public class MemorySmartQueue : SmartQueue
> > {
> > public override void poolForData()
> > {
> > // data available!
> > OnDataArrived( args ); // Fire the event
> > }
> > }
> >
> >
> > Hope this helps
> > --
> > Chris Taylor
> > http://dotnetjunkies.com/WebLog/chris.taylor/
> > "Elder Hyde" <no_way> wrote in message
> > news:%(E-Mail Removed)...
> > > Hey all,
> > >
> > > A class of mine needs to tell the outside world when its buffer is not
> > > empty. The problem is that C# seems to force you to put the
> > > event-raising code in the base class. To illustrate, consider what

I'll
> > > do in Java:
> > >
> > > public interface DataAvailabilityListener extends

> java.util.EventListener
> > {
> > > void dataArrived(DataAvailabilityEvent event);
> > > }
> > >
> > > then, in my base class, I can do this:
> > >
> > > public abstract class SmartQueue {
> > > addDataAvailabilityListener(DataAvailabilityListener listener);
> > > }
> > >
> > > then in my implementation class, say a memory-backed smart queue, I

can
> > > do this:
> > >
> > > public class MemorySmartQueue implements SmartQueue {
> > > public void poolForData() {
> > > // data available!
> > > while(iter.hasNext()) {
> > > DataAvailabilityListener lis =
> > > (DataAvailabilityListener)iter.next();
> > > lis.dataArrived(someEvent);
> > > }
> > > }
> > > }
> > >
> > > Simple and straighforward. However, consider a C# implementation: in

the
> > > interface, I may have something like this:
> > >
> > > public abstract class SmartQueue {
> > > public event DataAvailabilityEventHandler DataArrived;
> > > }
> > >
> > > Now, consider what I have to do in MemorySmartQueue:
> > >
> > > public class MemorySmartQueue : SmartQueue {
> > > public override void poolForData() {
> > > // data available!
> > > if(DataArrived == null) {
> > > // BZZZZTTT!!! Can only do this in SmartQueue!
> > > DataArrived(this, args);
> > > }
> > > }
> > > }
> > >
> > > I can't believe this. Either I'm missing a really obvious thing, or I
> > > have to deal with this... this... awkward mechanism. Why the hell
> > > doesn't it allow me to raise an event in the derived class? I don't

want
> > > to put any behaviour in my abstract class, I want to put just an

> > interface!
> > >
> > > Is there any way around this? (Plus I hope Whidbey will give us a Set
> > > collection, dammit).
> > >
> > > TIA!
> > > Elder

> >
> >

>
>



 
Reply With Quote
 
Guest
Posts: n/a
 
      17th Jan 2004
I would assume this is a rare case that we would need async events then if
its so much hassle.


I am basically trying to draw a similarity between Win32 PostMessage and
SendMessage. Usually I used PostMessage as a way to fire events rather than
SendMessage wheras on C# I am using the equivilent to SendMessage now.





"Chris Taylor" <(E-Mail Removed)> wrote in message
news:Oh#(E-Mail Removed)...
> Hi,
>
> You could use BeginInvoke, and remember to always call EndInvoke. The

events
> will still be fired synchroneously, but in a separate thread. Something

like
> the following should do, this will be limited to only one handler however.
>
> public virtual void OnDataArrived( EventArgs e )
> {
> if ( DataArrived != null )
> DataArrived.BeginInvoke( this, e, new AsyncCallback(
> DataArrivedCompleted ), null );
> }
>
> private void DataArrivedCompleted( IAsyncResult ar )
> {
> if ( DataArrived != null )
> DataArrived.EndInvoke( ar );
> }
>
> You could also just use a separate thread to fire the event in, that way

you
> can have multiple handlers.
>
> public virtual void OnDataArrived( EventArgs e )
> {
> if ( DataArrived != null )
> System.Threading.ThreadPool.QueueUserWorkItem( new
> System.Threading.WaitCallback( FireDataArrived ), e );
> }
>
> private void FireDataArrived( object e )
> {
> if ( DataArrived != null )
> DataArrived( this, (EventArgs)e );
> }
>
> Then you can also fire each handler individually.
>
> public virtual void OnDataArrived( EventArgs e )
> {
> if ( DataArrived != null )
> foreach( DataAvailabilityEventHandler d in
> DataArrived.GetInvocationList() )
> {
> d.BeginInvoke( this, e, new

AsyncCallback(DataArrivedEventComplete),
> d );
> }
> }
>
> private void DataArrivedEventComplete( IAsyncResult ar )
> {
> DataAvailabilityEventHandler e =
> (DataAvailabilityEventHandler)ar.AsyncState;
> e.EndInvoke( ar );
> }
>
> Of course you would have to make sure the caller is aware of this
> non-standard event calling and manage thread syncronization for shared

data
> etc. This code also lacks significant error handling, but should leave you
> with a number of options.
>
> Hope this helps
>
> --
> Chris Taylor
> http://dotnetjunkies.com/WebLog/chris.taylor/
> <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > How can we perform an Async event in C#?
> >
> > Events are Synchronous usually. Do we just call BeginInvoke, if so, how
> > would we do this?
> >
> > "Chris Taylor" <(E-Mail Removed)> wrote in message
> > news:#(E-Mail Removed)...
> > > Hi,
> > >
> > > It is standard to implement a method to fire the event, this method is

> the
> > > event name prefixed with 'On'. So in your case the base class would

have
> a
> > > OnDataArrived, which can be called from anywhere. This has the

advantage
> > of
> > > not having to cluter your code checking if the event has any delegates
> > > before firing and also gives the derived implementation an alternative

> and
> > > better performing method of handling the event by overriding the On...
> > > method.
> > >
> > > public abstract class SmartQueue
> > > {
> > > public event DataAvailabilityEventHandler DataArrived;
> > >
> > > // This is called to fire the event
> > > public void OnDataArrived( YourEventArgs e )
> > > {
> > > if ( DataArrived != null )
> > > DataArrived( this, e );
> > > }
> > > }
> > >
> > > public class MemorySmartQueue : SmartQueue
> > > {
> > > public override void poolForData()
> > > {
> > > // data available!
> > > OnDataArrived( args ); // Fire the event
> > > }
> > > }
> > >
> > >
> > > Hope this helps
> > > --
> > > Chris Taylor
> > > http://dotnetjunkies.com/WebLog/chris.taylor/
> > > "Elder Hyde" <no_way> wrote in message
> > > news:%(E-Mail Removed)...
> > > > Hey all,
> > > >
> > > > A class of mine needs to tell the outside world when its buffer is

not
> > > > empty. The problem is that C# seems to force you to put the
> > > > event-raising code in the base class. To illustrate, consider what

> I'll
> > > > do in Java:
> > > >
> > > > public interface DataAvailabilityListener extends

> > java.util.EventListener
> > > {
> > > > void dataArrived(DataAvailabilityEvent event);
> > > > }
> > > >
> > > > then, in my base class, I can do this:
> > > >
> > > > public abstract class SmartQueue {
> > > > addDataAvailabilityListener(DataAvailabilityListener listener);
> > > > }
> > > >
> > > > then in my implementation class, say a memory-backed smart queue, I

> can
> > > > do this:
> > > >
> > > > public class MemorySmartQueue implements SmartQueue {
> > > > public void poolForData() {
> > > > // data available!
> > > > while(iter.hasNext()) {
> > > > DataAvailabilityListener lis =
> > > > (DataAvailabilityListener)iter.next();
> > > > lis.dataArrived(someEvent);
> > > > }
> > > > }
> > > > }
> > > >
> > > > Simple and straighforward. However, consider a C# implementation: in

> the
> > > > interface, I may have something like this:
> > > >
> > > > public abstract class SmartQueue {
> > > > public event DataAvailabilityEventHandler DataArrived;
> > > > }
> > > >
> > > > Now, consider what I have to do in MemorySmartQueue:
> > > >
> > > > public class MemorySmartQueue : SmartQueue {
> > > > public override void poolForData() {
> > > > // data available!
> > > > if(DataArrived == null) {
> > > > // BZZZZTTT!!! Can only do this in SmartQueue!
> > > > DataArrived(this, args);
> > > > }
> > > > }
> > > > }
> > > >
> > > > I can't believe this. Either I'm missing a really obvious thing, or

I
> > > > have to deal with this... this... awkward mechanism. Why the hell
> > > > doesn't it allow me to raise an event in the derived class? I don't

> want
> > > > to put any behaviour in my abstract class, I want to put just an
> > > interface!
> > > >
> > > > Is there any way around this? (Plus I hope Whidbey will give us a

Set
> > > > collection, dammit).
> > > >
> > > > TIA!
> > > > Elder
> > >
> > >

> >
> >

>
>



 
Reply With Quote
 
Daniel O'Connell
Guest
Posts: n/a
 
      17th Jan 2004

"Elder Hyde" <no_way> wrote in message
news:%(E-Mail Removed)...
> Hey all,
>
> A class of mine needs to tell the outside world when its buffer is not
> empty. The problem is that C# seems to force you to put the
> event-raising code in the base class. To illustrate, consider what I'll
> do in Java:
>
> public interface DataAvailabilityListener extends java.util.EventListener

{
> void dataArrived(DataAvailabilityEvent event);
> }
>
> then, in my base class, I can do this:
>
> public abstract class SmartQueue {
> addDataAvailabilityListener(DataAvailabilityListener listener);
> }
>
> then in my implementation class, say a memory-backed smart queue, I can
> do this:
>
> public class MemorySmartQueue implements SmartQueue {
> public void poolForData() {
> // data available!
> while(iter.hasNext()) {
> DataAvailabilityListener lis =
> (DataAvailabilityListener)iter.next();
> lis.dataArrived(someEvent);
> }
> }
> }
>
> Simple and straighforward. However, consider a C# implementation: in the
> interface, I may have something like this:
>
> public abstract class SmartQueue {
> public event DataAvailabilityEventHandler DataArrived;
> }
>
> Now, consider what I have to do in MemorySmartQueue:
>
> public class MemorySmartQueue : SmartQueue {
> public override void poolForData() {
> // data available!
> if(DataArrived == null) {
> // BZZZZTTT!!! Can only do this in SmartQueue!
> DataArrived(this, args);
> }
> }
> }
>
> I can't believe this. Either I'm missing a really obvious thing, or I
> have to deal with this... this... awkward mechanism. Why the hell
> doesn't it allow me to raise an event in the derived class? I don't want
> to put any behaviour in my abstract class, I want to put just an

interface!

It is an annoying thing. The CLR does allow for a protected raise_
method(atleast, by a vauge reading), however C# doesn't appear to support
this currently(MC++ is the only one I know that does.
Anyway, if you don't want any serious implementation in your base class, you
can do

public abstract class BaseClass
{
public event MyEventHandler MyEvent
{
add
{
Delegate.Combine(myEventDelegate,value);
}
remove
{
Delegate.Remove(myEventDelegate,value);
}
}
//this will contain the invocation list, might wanna convert this
//to a protected property so that you don't *have* to back off
myEventDelegate.
protected MyEventHandler myEventDelegate;
}
(note the syntax may be a touch off, I'm working from memory).
I would not be adverse to allowing a
raise
{

}
style method to events, however convincing the C# team of such may be
substatial work.
>
> Is there any way around this? (Plus I hope Whidbey will give us a Set
> collection, dammit).
>
> TIA!
> Elder



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Setting an Event Handler on data member of parent class in derived class Jon Skeet [C# MVP] Microsoft C# .NET 1 13th Jan 2006 07:30 AM
Prevent IDE generating "private componets" in derived Form class =?Utf-8?B?dG9tYQ==?= Microsoft Dot NET Framework Forms 0 10th May 2005 02:01 PM
Having trouble with an event in a derived class =?Utf-8?B?UElFQkFMRA==?= Microsoft Dot NET Framework 4 22nd Apr 2005 12:51 AM
How do I isolate event-generating code in a derived class? Elder Hyde Microsoft C# .NET 18 25th Feb 2004 06:34 PM
RE: Framework 1.1 bug. Derived class generating Abstract base class stubs. Sometimes. MSFT Microsoft VB .NET 3 4th Nov 2003 06:53 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 03:16 AM.