I have a public interface. One of its methods is marked internal. And it has to be - it takes an argument that is an internal type.
I write a public class that implements this interface, I do so via a method that is itself marked internal.
public class CP { }
internal class CI { }
public interface IFoo {
public void MethodP(CP arg);
internal void MethodI(CI arg);
}
public class Foo : IFoo {
public void MethodP(CP arg) { }
internal void MethodI(CI arg) { }
}
I get an error complaining that Foo
doesn't implement IFoo.MethodI
and that Foo.MethodI
can't be the implementation because it is not public.
However, I can't make it public even if I wanted to - that would give an error about a public method having an internal argument.
Surely the method in a class that implements a method of an interface should be "at least as accessible" as the method of the interface. But requiring public seems like a mistake? A left-over from when all interface methods were public?
Am I missing a good reason for this?
You can be explicit about it, like this:
public class Foo : IFoo {
public void MethodP(CP arg) { }
void IFoo.MethodI(CI arg) { }
}
But now any internal code that has a Foo
has to weirdly cast it to an IFoo
in order to call MethodI
.
C# has allowed non-public interface methods with introduction of default interface methods which was quite a controversial feature and arguably not fully (some might even use "well" instead of "fully") designed.
There was original discussion what to do with with implementing such methods (docs):
Closed Issue: How does one implement a non-public interface member in a class?
Decision: You can only implement non-public interface members explicitly. See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md#dim-implementing-a-non-public-interface-member-not-in-list.
Though linked LDM has some other wording as far as I can see.
There are discussions about fixing this in future for example: C# Language Design Meeting for Apr 25th, 2022: Inconsistencies around accessibility checks for interface implementations.
Also currently it seems also possible to explicitly implement such method:
public class Foo : IFoo {
public void MethodP(CP arg) { }
void IFoo.MethodI(CI arg) { }
}
Demo @sharplab
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With