Inheritance or composition

G

Guest

Hi,

I want to create a class that sends/receives data from the serial port.
There is such a class in .NET v 2.0 but what I need is a serial port with
some extra features. For example I want my class to raise a certain event not
only when data has been received but also upon some additional condition. If
the class I want to extend was an Windows.Forms class I could write this:

class MyButton:Button
{
protected override void OnClick(...)
{
if ( IsMonday ()) // my button can be clicked only on
Mondays
{
base.OnClick(...);
// raise the event by calling subscribers
}

}
}

The problem is that the SerialPort class has no overrides, only events. This
means that I have to use it like this:

class MySerialPort
{
private SerialPort sp;
..
}
But this means that I have to add functions like this:

MySerialPort.Open()
{
sp.Open();
}

which is a lot of code.
So I decided to set sp public:

class MySerialPort
{
public SerialPort sp;
..
}

Now I can write:

MySerialPort msp=new MySerialPort;
msp.sp.Opne();

The problem here is that I want to have a function Send() in my port that
not only sends a byte but also specifies for example a timeout, ie the caller
of this function expects an answer within certain time. This means that I
have to intercept the calls to SerialPort.Send() and which means I have to go
back to have SerialPort as private:

MySerialPort.Send(byte b, int timeout)
{
SerialPort.Send(b);
StartSomeTimer();
}
MySerialPort.TimerCallback()
{
// tell subscribers the transaction failed
}

Is this the only way to extend the functionality of a class like SerialPort,
which has no overridables, by composition (and lot of code)? Can inheritanc
ebe used somehow?

Thank you
 
A

Alberto Poblacion

Z said:
Is this the only way to extend the functionality of a class like
SerialPort,
which has no overridables, by composition (and lot of code)? Can
inheritanc
ebe used somehow?

You could use Inheritance and then use the keyword "new" for shadowing
(instead of overriding) the original functions where you want to add or
alter functionality. Your shadow function could then call
base.TheOriginalFunction as needed.
 
N

Nicholas Paldino [.NET/C# MVP]

Z,

Why not derive from SerialPort and subscribe to the events yourself?
 
B

Bill Butler

The problem here is that I want to have a function Send() in my port
that
not only sends a byte but also specifies for example a timeout, ie the
caller
of this function expects an answer within certain time. This means
that I
have to intercept the calls to SerialPort.Send() and which means I
have to go
back to have SerialPort as private:

You could do this all easily through composition.
Just create the SerialPort prior to creating your Object.
Pass the SerialPort in as a parameter.
Do all setup operations on the SerialPort directly, but call Send on
your wrapper.

This is a similar relationship to stream/streamwriter.


SerialPort sp = new SerialPort();
// configure the serial port

Have your class take a SerialPort in it's constructor.
MySerialPort wrapper = new MySerialPort(sp);

wrapper.Send(b, 1000);


class MySerialPort
{
private SerialPort serialport;
public MySerialPort (SerialPort serialport)
{
this.serialport = serialport;
}
}
MySerialPort.Send(byte b, int timeout)
{
serialport.Send(b);
StartSomeTimer();
}
MySerialPort.TimerCallback()
{
// tell subscribers the transaction failed
}

Bill
 
J

Jon Skeet [C# MVP]

Alberto Poblacion said:
You could use Inheritance and then use the keyword "new" for shadowing
(instead of overriding) the original functions where you want to add or
alter functionality. Your shadow function could then call
base.TheOriginalFunction as needed.

That would then fail for any methods which took a SerialPort parameter,
however. The failure would quite possibly be somewhat hard to spot,
too. The "new" modifier for methods should rarely be used other than
for versioning reasons, IMO.

Composition is a neater solution here, I reckon.
 
G

Guest

Bill Butler said:
You could do this all easily through composition.
Just create the SerialPort prior to creating your Object.
Pass the SerialPort in as a parameter.
Do all setup operations on the SerialPort directly, but call Send on
your wrapper.

This is a similar relationship to stream/streamwriter.


SerialPort sp = new SerialPort();
// configure the serial port

Have your class take a SerialPort in it's constructor.
MySerialPort wrapper = new MySerialPort(sp);

wrapper.Send(b, 1000);


class MySerialPort
{
private SerialPort serialport;
public MySerialPort (SerialPort serialport)
{
this.serialport = serialport;
}
}
MySerialPort.Send(byte b, int timeout)
{
serialport.Send(b);
StartSomeTimer();
}
MySerialPort.TimerCallback()
{
// tell subscribers the transaction failed
}

Bill

Hi,

Thank you for your replies. I think I will go for composition. I cant use
inheritance
as Nicholas Paldino suggests because I do not want the original event, I
want the event raised upon certain additional conditions.(which I impose).

Thank you again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top