Question

I tend to favor explicit interface implementations over implicit ones, as I think programming against the interface as opposed to against an implementation, is generally preferable, plus when dealing with web-services it is often a necessity.

That said, I was wondering why the following is illegal with an explicit interface declaration and legal with an implicit one:

interface IConnection
{
    string ConnectionString { get; }
}

class Connection1 : IConnection
{
    // private set is illegal, won't compile
    string IConnection.ConnectionString { get; private set; }
}

class Connection2 : IConnection
{
    // private set is legal now, it is not part of the interface
    string ConnectionString { get; private set; }
}

I know how to fix this, as it is legal to have both an explicit and implicit interface, plus I can make the implicit interface implementation completely private.

Yet I am wondering about the reasoning behind this. Because technically, the internally compiled private method set_IConnection_ConnectionString does not need to be part of the interface, right? It could just be seen as an auxiliary setter, not part of the interface, as it is in the implicit implementation situation.

Update: as a bonus, the seemingly confusing, and in my opinion not quite right compile error you receive is the following:

The accessibility modifier of the accessor must be more restrictive than the property Connection1.ConnectionString

Excuse me, more restrictive than private, how... what?

Was it helpful?

Solution

The only way to invoke an explicit interface member is to cast the object to the correct interface and then invoke the member on that interface. But once you've cast to IConnection, the IConnection.ConnectionString has no setter.

So there's no way to invoke this private setter method.

OTHER TIPS

The problem is that when an interface member is declared explicitly, the compiler generates a private implementation with an "unpronounceable" name, and provides no means by which code--even within the implementing class--to refer to that implementation.

Basically, when one says void IFoo.Moo(), one is saying that one does not wish to define a name Moo within the class scope; consequently, the compiler won't. In order for private set to work, the member would have to be a "pronounceable" name, and the fact that the member was explicitly implemented is taken as an indication that one does not want the name to be Moo.

In practice, the remedy here is probably the same as for many other cases where it's necessary to have an interface implementation whose name is pronounceable, but which is not exposed publicly under its name: declare an interface implementation which does nothing but chain to other members which have the proper accessibility, e.g. if derived classes should not be able to affect the value the value:

private readonly int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}

or, if derived classes should be able to affect it, either

protected int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}

or

private int _foo = whatever;
protected virtual int setFoo(int value) { _foo = value; }
protected virtual int getFoo() { return _foo; }
public int IFOO.Foo { get {return getFoo();}}

In vb.net, interfaces may be implemented using protected class members, but C# offers no such facility.

I think the core of the problem is that the interface only has what it needs. If it isn't public, it naturally isn't part of the interface. When you explicitly implement the interface it does not, therefore, exist.

In the implicit case, your code fits the interface, but is not totally constrained by it. You can add on more things if needed.

Getting information on why this is would require a designer of the language to answer you. It seems logical to me, however: if it isn't part of the interface, you cannot implement/access it as part of the interface.

The property declaration is an atomic thing containing a getter and a setter. It should match the interface.

If you would allow this, then apparently the getter and setter are seen as different things. In that case there is no use to limiting it to privates either. In that case the interface just dictates that there has to be a property which can be read, and you are free to make it writable as well.

Anyway, apparently it's a design decision to make it atomic.

Perhaps the explicit interface implementation should not be seen as part of the class itself but rather as a kind of adapter from your interface to the class. Given this view; consider the following implementation:

public interface I {
    string S { get; set; }
}

class C : I {
    public C() {
        this.S = "Hello World"; 
        //compile error: explicit implementation not accessible
    }

    string I.S { get; set; }
}

In class C, the property S is not even privately accessible because it is an explicit implementation. Would it not be bad design in the first place to have a concrete implementation of a field not be accessible by the implementation itself?

Furthermore, in your example creating a setter for the explicit implenentation would never be accessible; since the property is only accessible when cast to the IConnection interface. There it only has a getter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top