c# - Attempting to merge classes using Generics, not working -



c# - Attempting to merge classes using Generics, not working -

i have 3 classes i'd talk merging single class. they're same exception of subscribe method, more @ observer.onnext(...)

i end with:

public class observableserialport<t> : iobservable<t>, idisposable

which instantiation be:

var port = new observableserialport<byte[]>("com4");

is valid candidate using generics?

public class observableserialport_bytearray : iobservable<byte[]>, idisposable { private readonly serialport _serialport; public observableserialport_bytearray(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) { _serialport = new serialport() { portname = portname, baudrate = baudrate, parity = parity, databits = databits, stopbits = stopbits, dtrenable = true, rtsenable = true, encoding = new asciiencoding(), readbuffersize = 4096, readtimeout = 10000, writebuffersize = 2048, writetimeout = 800, handshake = handshake.none, parityreplace = 63, newline = "\n", }; _serialport.open(); } public idisposable subscribe(iobserver<byte[]> observer) { if (observer == null) throw new argumentnullexception("observer"); // processing when incoming event has occurred var rcvevent = observable.fromeventpattern<serialdatareceivedeventhandler, serialdatareceivedeventargs>( h => h.invoke, h => _serialport.datareceived += h, h => _serialport.datareceived -= h) .subscribe(e => { if (e.eventargs.eventtype == serialdata.eof) { observer.oncompleted(); } else { var buf = new byte[_serialport.bytestoread]; var len = _serialport.read(buf, 0, buf.length); // notify observer had received info (byte[]) observable.range(0, len).foreach(i => observer.onnext(buf)); } }); // processing when error event occurs var errevent = observable.fromeventpattern<serialerrorreceivedeventhandler, serialerrorreceivedeventargs> (h => _serialport.errorreceived += h, h => _serialport.errorreceived -= h) .subscribe(e => observer.onerror(new exception(e.eventargs.eventtype.tostring()))); // cancel event registration when dispose called homecoming disposable.create(() => { rcvevent.dispose(); errevent.dispose(); }); } public void send(string text) { _serialport.write(text); } public void send(byte[] text) { _serialport.write(text, 0, text.length); } public void dispose() { _serialport.close(); } } public class observableserialport_byte : iobservable<byte>, idisposable { private readonly serialport _serialport; public observableserialport_byte(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) { _serialport = new serialport() { portname = portname, baudrate = baudrate, parity = parity, databits = databits, stopbits = stopbits, dtrenable = true, rtsenable = true, encoding = new asciiencoding(), readbuffersize = 4096, readtimeout = 10000, writebuffersize = 2048, writetimeout = 800, handshake = handshake.none, parityreplace = 63, newline = "\n", }; _serialport.open(); } public idisposable subscribe(iobserver<byte> observer) { if (observer == null) throw new argumentnullexception("observer"); // processing when incoming event has occurred var rcvevent = observable.fromeventpattern<serialdatareceivedeventhandler, serialdatareceivedeventargs>( h => h.invoke, h => _serialport.datareceived += h, h => _serialport.datareceived -= h) .subscribe(e => { if (e.eventargs.eventtype == serialdata.eof) { observer.oncompleted(); } else { var buf = new byte[_serialport.bytestoread]; var len = _serialport.read(buf, 0, buf.length); // notify observer had received info 1 byte @ time observable.range(0, len).foreach(i => observer.onnext(buf[i])); } }); // processing when error event occurs var errevent = observable.fromeventpattern<serialerrorreceivedeventhandler, serialerrorreceivedeventargs> (h => _serialport.errorreceived += h, h => _serialport.errorreceived -= h) .subscribe(e => { observer.onerror(new exception(e.eventargs.eventtype.tostring())); }); // cancel event registration when dispose called homecoming disposable.create(() => { rcvevent.dispose(); errevent.dispose(); }); } public void send(string text) { _serialport.write(text); } public void send(byte[] text) { _serialport.write(text, 0, text.length); } public void dispose() { _serialport.close(); } } public class observableserialport_string : iobservable<string>, idisposable { internal readonly serialport _serialport; public observableserialport_string(string portname, int baudrate = 19200, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) { _serialport = new serialport() { portname = portname, baudrate = baudrate, parity = parity, databits = databits, stopbits = stopbits, dtrenable = true, rtsenable = true, encoding = new asciiencoding(), readbuffersize = 4096, readtimeout = 10000, writebuffersize = 2048, writetimeout = 800, handshake = handshake.none, parityreplace = 63, newline = "\n", }; _serialport.open(); } public idisposable subscribe(iobserver<string> observer) { if (observer == null) throw new argumentnullexception("observer"); // processing when incoming event has occurred var rcvevent = observable.fromeventpattern<serialdatareceivedeventhandler, serialdatareceivedeventargs>(h => h.invoke, h => _serialport.datareceived += h, h => _serialport.datareceived -= h) .select(e => { if (e.eventargs.eventtype == serialdata.eof) { observer.oncompleted(); homecoming string.empty; } // , converting received info string var buf = new byte[_serialport.bytestoread]; _serialport.read(buf, 0, buf.length); homecoming encoding.ascii.getstring(buf); }) .scan(tuple.create(new list<string>(), ""), (t, s) => { // linked time of received info s , lastly remaining t.item2. var source = string.concat(t.item2, s); // min set in item1 newline code attached, notify observer. // amount of line feed code not attached placed in item2, , processed when receiving next data. var items = source.split('\n'); homecoming tuple.create(items.take(items.length - 1).tolist(), items.last()); }) .selectmany(x => x.item1) // item1 notify observer. .subscribe(observer); // processing when error event occurs var errevent = observable.fromeventpattern<serialerrorreceivedeventhandler, serialerrorreceivedeventargs>(h => _serialport.errorreceived += h, h => _serialport.errorreceived -= h) .subscribe(e => observer.onerror(new exception(e.eventargs.eventtype.tostring()))); // cancel event registration when dispose called homecoming disposable.create(() => { rcvevent.dispose(); errevent.dispose(); }); } public void send(string text) { _serialport.write(text); } public void send(byte[] text) { _serialport.write(text, 0, text.length); } public void dispose() { _serialport.close(); } }

mostly "no", not valid candidate using generics, qualified "somewhat" because of presence of generic interface implemented 3 classes - iobservable<t>.

an introduction c# generics says:

generics allow define type-safe info structures, without committing actual info types. results in important performance boost , higher quality code, because reuse info processing algorithms without duplicating type-specific code.

here are unavoidably type committed (three specific) info types, , code each type is not same there's no reuse potential.

there interface implementation generic.

mostly, believe you're looking old-fashioned inheritance, because there is plenty of mutual "boilerplate" code in no way generic (type specific) mutual observableserialport classes. let's start that.

move mutual code new base of operations class:

public abstract class observableserialport : idisposable { protected readonly serialport _serialport; protected observableserialport(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) { _serialport = new serialport() { // mutual serialport construction code here. removed create reply more readable. }; _serialport.open(); } public void send(string text) { _serialport.write(text); } public void send(byte[] text) { _serialport.write(text, 0, text.length); } public void dispose() { _serialport.close(); } }

retain 3 classes derived classes of base of operations class mutual code refactored away:

public class observableserialport_byte : observableserialport, iobservable<byte> { public observableserialport_byte(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) : base(portname, baudrate, parity, databits, stopbits) { } public idisposable subscribe(iobserver<byte> observer) {

on sec wave of refactoring bit closer asked changing base of operations class definition to:

public abstract class observableserialport<t> : idisposable, iobservable<t>

and adding base of operations class:

public abstract idisposable subscribe(iobserver<t> observer);

first derived class now:

public class observableserialport_bytearray : observableserialport<byte[]> { public observableserialport_bytearray(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) : base(portname, baudrate, parity, databits, stopbits) { } public override idisposable subscribe(iobserver<byte[]> observer) {

and sec is:

public class observableserialport_byte : observableserialport<byte> { public observableserialport_byte(string portname, int baudrate = 9600, parity parity = parity.none, int databits = 8, stopbits stopbits = stopbits.one) : base(portname, baudrate, parity, databits, stopbits) { } public override idisposable subscribe(iobserver<byte> observer) {

on top of that, there code in subscribe() mutual (not generic) refactor protected function in base of operations class too.

note, technically could create single generic class checks of 3 concrete types t is, a) there no suitable where constraint in fact instantiate other, invalid, types such as, say, double , b) you'd have perform type comparisons isn't generic @ , totally pointless. going original quote, doing way not freeing committing actual info types, not give higher quality code, , offer no farther reuse of info processing algorithms without duplicating type-specific code first solution above. same criticism might levelled @ sec solution think can away if base of operations class required implement iobservable<t>.

c# generics serial-port system.reactive

Comments

Popular posts from this blog

assembly - What is the addressing mode for ld, add, and rjmp instructions? -

vowpalwabbit - Interpreting Vowpal Wabbit results: Why are some lines appended by "h"? -

Is there a way to convert an HTML page styled with Bootstrap CSS into email-compatible html? -