Why must an C# interface method implemented in a class be public?
Asked Answered
S

3

32

I have a class which inherits an interface. An interface member method is implemented in my class without an access modifier (so, by default it's private ) .

I am getting the error "cannot implement an interface member because it is not public".

Why it is not allowed? Can't I override the accessibility?

Satiate answered 30/8, 2011 at 4:9 Comment(0)
S
45

Here's an example of why it doesn't make sense to be able to override the visibility:

interface someI
{
    void doYourWork();
}
public class A : someI
{
    public void doYourWork()
    {
        //...
    }
}

public class B : someI
{
    private void doYourWork()
    {
        //...
    }
}
void Main()
{
    List<someI> workers = getWorkers();
    foreach(var worker in workers)
        worker.doYourWork();
}

What happens when your worker is of type B? You're calling a method as if it were public, but it's a private method. If you want this functionality, then it's not really a private method is it?

If you only want it to be public when referenced through your interface, then you can define it as such:

public class B : someI
{
    void someI.doYourWork()
    {
        //...
    }
}

And you end up with this:

var b = new B();
b.doYourWork(); // Not accessible
((someI)b).doYourWork(); // Accessible
Strew answered 30/8, 2011 at 4:28 Comment(4)
I would suggest that for unsealed classes, interfaces whose implementations aren't going to expose public class members with the same names and signatures should be implemented using protected virtual members; unfortunately, the closest one can come to doing that in C# is to have an interface implementation simply call a protected virtual method. Otherwise, if a derived class re-implements an interface there will be no way to call the parent implementation.Misusage
@Misusage Maybe it's just early, but I'm not sure I'm following you; what do you mean by Otherwise, if a derived class re-implements an interface there will be no way to call the parent implementation ? Why do you want to have a protected method implementing an interface (you won't be able to access it through the interface in this case; only in derived classes which may not even know what interfaces they're implementing)Strew
In vb.net, one can say: Protected Overridable Sub DoSomethingImpl() Implements IDoSomething.DoSomething; outside code will only be able to call that method via the interface, but a derived class will be able to override the method and, within the override, call the parent method. In C#, it would be useful to be able to likewise use a protected method to implement an interface, but the people in charge of the spec do not allow that option. The closest one can come would be to explicitly implement the interface with a method that would call protected method DoSomethingImpl(). Note that...Misusage
...the name of the implementing method could be DoSomething() rather than DoSomethingImpl(), but using the former name would prevent a derived class from exposing a public DoSomething() method.Misusage
R
23

Methods have to be implemented public because they have to be callable through the interface, thus from where the interface is accessible as a type.

You have a few options here to "change" the visibility of that method. Given:

public interface IFoo 
{
    bool IsFoo();
}

A. Implement the method explicitly

public class Foo : IFoo
{
    bool IFoo.IsFoo() { return true; }
}

The method will only be available through the interface (IFoo in this case.)

B. Change the visibility of the interface

Define the interface as internal instead of public. As a consequence, however, Foo will have to be internal too.

Richella answered 30/8, 2011 at 4:12 Comment(1)
In other languages such as vb.net, no particular accessibility is required for a method which implements an interface. C# requires that implicit interface implementations must be public because there's no other keyword or notation to indicate that a named class member should also be regarded as an interface implementation.Misusage
M
6

Requiring that an interface implementation be public is simply a logical requirement. When you implement an interface, you're telling the compiler "Hey I implement every method on this interface". So making the method private makes it no longer accessible - and logically not implemented. Interfaces serve as a contract to code that uses your object saying you can always call any method defined in the interface on my object. If the implementing method were private, that would not longer be true.

If you want to hide your implementation from, say Intellisense, then you can simply implement the method explicitly as @Bryan mentions.

Melise answered 30/8, 2011 at 4:18 Comment(1)
"Interfaces serve as a contract to code that uses your object saying you can always call any method defined in the interface on my object." That's not strictly true. It means that you can cast an instance of the class to the interface, and then call the interface methods through the interface reference. THAT is the contract, NOT the ability to call the interface's methods without first casting to the interface. Of course you should usually expose the interface methods without requiring the cast as well, but that is neither a technical requirement nor always a logical requirement.Stereobate

© 2022 - 2024 — McMap. All rights reserved.