admin管理员组

文章数量:1125579

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.

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.

Share Improve this question edited 2 days ago DarkBee 15.8k8 gold badges69 silver badges110 bronze badges asked Jan 9 at 6:53 PreventRagePreventRage 2392 silver badges11 bronze badges 3
  • 2 This is where work on speccing has fallen behind. Unfortunately the latest published version of the C# spec still says that interfaces have only public members so it's hard to go to the spec and work out what it has to say on the matter. – Damien_The_Unbeliever Commented Jan 9 at 7:27
  • 1 ^^ This. But outside that: If I'd find a non-public member in an interface in our codebase, I'd ask the author for the very good reason they must have had. The ability to do this probably goes back to a very specific use case and it should probably stay contained to that. ... Haha - I just asked a colleage about it. He said "you can't do that". He just learned something :D – Fildor Commented Jan 9 at 7:33
  • 2 @Damien_The_Unbeliever as far as I can see it is not about speccing, language team has not made a final decision what to do with such cases. – Guru Stron Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 6

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

本文标签: cWhy must an internal method of a public interface be implemented via a public methodStack Overflow