1

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)

2
  • 3
    It might be an EventArgs, but the signatures aren't the same. Surely you can see that? Commented Oct 31, 2016 at 12:22
  • your getting the error message 'SerialCommunicator' does not implement interface member 'ICommunicator.Data_Input(object, EventArgs)' becuase SerialCommunicator does not implement the interface member ICommunicator.Data_Input(object, EventArgs). you can't type cast like this in interfaces Commented Oct 31, 2016 at 12:26

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you Gilad, but can I avoid writing the type of the ICommunicator when declaring an object of it? I want to encapsulate the communication type from my app, and with the way you suggest, i have to write this: ICommunicator<SerialDataReceivedEventArgs> comm; public Facade() { comm = new SerialCommunicator(); }
@David - What you mean to avoid writing the type of ICommunicator? Do you mean when going with the generics? No.. You must specify the type of the generic parameter of the class (of also have your derived generic)
The class that creates the ICommunicator instance must not know about the type. How can i pass the type to the containing class?
@David - You must somewhere specify the type.. You can: A. specify another non-generic interface what will contain all the other properties/methods and then a generic one that derives from it. The in the Facade your parameter is of the non genetic type but is initialized with the derived class of the generic.B. Another option is to have the Facade generic... C. Don't use generics at all and just in the specific implementation check if the Args is from the needed type and if not throw exception/write log/whatever makes sense in your scenario
Thank you, that really helped me!
2

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.

Although SerialDataReceivedEventArgs is an EventArgs, your interface declares a method that can be passed an EventArgs and the method you implemented does not accept an EventArgs, but only the more specialized SerialDataReceivedEventArgs. So your implementation does not fulfill the contract that is required.

Comments

1

Interface:

void Data_Input(object sender, EventArgs e);

Your implementation:

public void Data_Input(object sender, SerialDataReceivedEventArgs e)

You need to have this:

public void Data_Input(object sender, EventArgs e)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.