David David - 1 month ago 5
C# Question

c# interface implementation error

I'm developing a communication manager for my app, that is designed like this:

ICommunicator interface, a general communicator.

public interface ICommunicator
{
bool openConnection();
bool closeConnection();

bool isConnectionOpen();
Form getConfigurationForm();

void Data_Input(object sender, EventArgs e);
}


and currently, a single concrete communicator which is SerialCommunicator:

public class SerialCommunicator : ICommunicator
{
public delegate bool setPortDelegate(string portName);
public delegate bool setBaudRateDelegate(int baudRate);

private SerialPort serial;

public SerialCommunicator()
{
serial = new SerialPort();
loadDefaultSerialPreset(serial);
serial.DataReceived += Data_Input;
}

public bool openConnection()
{
if (serial.IsOpen)
{
return false;
}
try
{
serial.Open();
}
catch (Exception)
{
//could not open the port
return false;
}

return serial.IsOpen;
}

public bool closeConnection()
{
try
{
serial.Close();
}
catch (Exception)
{
return false;
}
return !serial.IsOpen;
}

public bool isConnectionOpen()
{
return this.serial.IsOpen;
}

public bool sendData(String text)
{
if (!this.serial.IsOpen)
{ return false; }

return true;
}

public void Data_Input(object sender, SerialDataReceivedEventArgs e)
{
String s = serial.ReadLine();
//tbd
}

public Form getConfigurationForm()
{
return new portConf(setPortName, setBaudRate);
}

private bool setPortName(string portName)
{
if (portName == null || portName.Length < 1 || !portName.StartsWith("COM"))
{
return false;
}
if (serial.IsOpen)
{
return false;
}
serial.PortName = portName;
return true;
}

private bool setBaudRate(int baudRate)
{
if (baudRate < 9600 || baudRate > 115200)
{
return false;
}
if (serial.IsOpen)
{
return false;
}
serial.BaudRate = baudRate;
return true;
}

private void loadDefaultSerialPreset(SerialPort s)
{
//default preset
s.BaudRate = 115200;
s.PortName = "COM1";
//default settings
s.DataBits = 8;
s.DiscardNull = false;
s.DtrEnable = false;
s.Handshake = Handshake.None;
s.Parity = Parity.None;
s.ParityReplace = 63;
s.ReadBufferSize = 4096;
s.ReadTimeout = -1;
s.ReceivedBytesThreshold = 1;
s.RtsEnable = false;
s.StopBits = StopBits.One;
s.WriteBufferSize = 2048;
s.WriteTimeout = -1;
}
}


the problem is, the compiler says that SerialCommunicator does not implement the interface:


'SerialCommunicator' does not implement interface member 'ICommunicator.Data_Input(object, EventArgs)'


I can not understand why it gives me that error. I do have the
Data_Input(object, SerialDataReceivedEventArgs)
, although every
SerialDataReceivedEventArgs
is also an
EventArgs
object.

Why does the compiler gives me that problem, and how can I fix it (I do need that event for other types of communication)

Answer

These too:

//Interface
void Data_Input(object sender, EventArgs e);
// Derived class
public void Data_Input(object sender, SerialDataReceivedEventArgs e)

Are not the same thing - They are 2 different types. When implementing an interface the signatures must be identical to those in the interface.

You should change the derived to be exactly like the interface or use a generic parameter + constraint.

//Interface
public interface ICommunicator<TEventArgs>
    where TEventArgs : EventArgs
{
    void Data_Input(object sender, TEventArgs e);
}

//Derived
public class SerialCommunicator : ICommunicator<SerialDataReceivedEventArgs>
{
    public void Data_Input(object sender, SerialDataReceivedEventArgs e)
    {
        throw new NotImplementedException();
    }
}

Even if you do not use the generics here, keep in mind that though the method will have a EventArgs parameter to it you can of course pass a derived type to it.