I have been refactoring the codebase of the project that I am currently on so that classes/interfaces which are not useful beyond the confines of the assembly should be declared as internal (rather than public). But I've run into a problem with the following code:
internal interface IFirstInterface
{
...
}
internal interface ISecondInterface
{
IFirstInterface First{ get; }
...
}
public class Implementer : ISecondInterface
{
public IFirstInterface First {get; private set;}
...
}
My questions:
Why do members of internal interfaces have to be publicly implemented? If you implement the interface on an internal class, shouldn't the implemented members be internal? This is not a big issue since the interface members won't be publicly accessible anyway, given the class is internal. It just seems counter intuitive.
The main problem is with the scenario above since I cannot have a public getter for IFirstInterface since it is purportedly an internal interface i.e. I get the following error from the compiler:
Inconsistent accessibility: property type 'IFirstInterface' is less accessible than property 'Implementer.First'
Is there any way around this?
Note: I realise that there is probably little value in this refactoring exercise but I thought it would be a good way for me to understand more deeply the implications of the internal modifier.
Just to note - the code you've actually provided does compile, because Implementer
is an internal class. The problem comes when Implementer
is public.
The way round this is to use explicit interface implementation:
public class Implementer : ISecondInferface
{
private IFirstInterface first;
IFirstInterface ISecondInterface.First { get { return first; } }
}
You can't have the setter in there, because you're explicitly implementing the interface which doesn't define the setter. You could do this as an alternative:
public class Implementer : ISecondInterface
{
internal IFirstInterface First { get; private set; }
IFirstInterface ISecondInterface.First { get { return First; } }
}
It's unfortunate that internal interfaces have public members - it does complicate things like this. It would be strange for a public interface to have an internal member (what would it be internal to - the implementer or the declarer?) but for internal interfaces it makes a lot more sense.