C# internal interface with internal implementation

Pete picture Pete · May 24, 2011 · Viewed 47.4k times · Source

I've struck upon something I don't really understand.

I have a project, where I have an interface that is internal. The class that implements that interface is also internal. In the implementation of the interface, I make all the members that I implement, internal. I did not do an explicit implementation.

I have two interfaces and two classes that implement those interfaces where this works fine.

It would look something like this:

internal interface IA
{
    void X();
}

and then

internal class CA : IA
{
    internal void X()
    {
        ...
    }
}

This works fine for the two aforementioned classes. But when I try to do it with another interface and class, it doesn't work. In fact, for the example above, I get the error:

'WindowsFormsApplication1.CA' does not implement interface member 'WindowsFormsApplication1.IA.X()'. 'WindowsFormsApplication1.CA.X()' cannot implement an interface member because it is not public.

I realize I can make the methods public or do an explicit implementation (and omit the internal and public modifiers), but I'm simply confused as to why it works with the two classes it works with and yet I seem to be unable to replicate it anywhere else.

Butchering the code a bit (because it's confidential), this is one of the ones that actually works in my project.

internal interface IScanner
{
    void SetHardware(Hardware hardware);
    void Start();
    void PauseScan();
    void ResumeScan();
    void Stop();
    bool InScan { get; }
    event ScanCompleteHandler ScanComplete;
}

Then I have the class:

internal class MyScanner : IScanner
{
    internal void SetHardware(Hardware hardware)
    {
       ...
    }

    internal void Start()
    {
        ...
    }

    internal void Stop()
    {
        ...
    }

    internal void PauseScan()
    {
        ...
    }

    internal void ResumeScan()
    {
        ...
    }

    internal bool InScan
    {
        get
        {
            ...
        }
    }

    internal event ScanCompleteHandler ScanComplete;
}

To make things even stranger, I created another internal class called Temp. I then had it implement the IScanner interface and I copied and pasted the implementation from MyScanner over to it and it won't compile, giving me the error that: "cannot implement an interface member because it is not public."

Can anyone explain this inconsistency?

Thanks

(Updated to fix a typo and clarify some text)

EDIT: Additional Information

I ran the code through reflector and my implementations have been compiled as explicit implementations, even though they aren't explicit. Reflector shows no signs of the internal keywords. All I can guess is that this is some sort of glitch in the compiler that, for some reason, allowed me to make them internal and implicit and that it somehow resolved that as being an explicit implementation.

I've looked over the code a number of times. I can't find any other explanation for it.

Answer

Reddog picture Reddog · May 25, 2011

If you are implicitly implementing an interface I believe that the member must be declared public. In your example, CA attempts to implicitly implement the X() method but isn't declared public. If you want to keep X() as internal then you should use explicit interface implementation.

void IA.X() { /* stuff */ }

However, I'll also add that making the X() method public wouldn't do any harm anyway as the class is internal so that member is already restricted by that access modifier... That is, it's already effectively internal... So you might as well just make it public!