1

Given the interface definition and it's implementation:

public interface IArithmetic
{
    int Summation { get; }
    void Add(int x, int y);
}

public class Calculator : IArithmetic
{
    public int Summation { get; private set; }

    void IArithmetic.Add(int x, int y)
    {
        Summation = x + y;
    }
}

A syntax error occurs when the implementation of Summation is made explicit

public class CalculatorB : IArithmetic
{   
    // error: "private set;"
    int IArithmetic.Summation { get; private set; }

    void IArithmetic.Add(int x, int y)
    {
        Summation = x + y;
    }
}

The accessibility modifier of 'CalculatorB.IArithmetic.Summation.set' accessor must be more restrictive than the property or indexer 'CalculatorB.IArithmetic.Summation'

Is there an accessor more restrictive than private? I'm not sure what the problem is here??


Below the set accessor is modified (no pun) to fix CalculatorB's syntax error.

public interface IArithmetic2
{
    int Summation { get; set; }

    void Add(int x, int y);
}

public class Calculator2 : IArithmetic2
{
    int IArithmetic2.Summation { get; set; }

    void IArithmetic2.Add(int x, int y)
    {
        // syntax error
        Summation = x + y;
    }        
}

The name 'Summation' does not exist in the current context.

I'm not sure what causes this resulting syntax error?

samus
  • 6,102
  • 6
  • 31
  • 69
  • 2
    An explicit interface implementation means that `Calculator`'s implementation of `IArithmetic` is only "visible" on a `Calculator` instance when explicitly cast to `IArithmetic`: `((IArithmetic)myCalc).Add()`. As dcg notes, this is useful when you're implementing multiple interfaces with like-named methods or properties. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:25
  • @EdPlunkett Like polymorphism via interfaces (as opposed to inheritance), for example? – samus Jun 14 '17 at 14:34
  • I guess you could say that. But it reminds me more of namespacing. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:38
  • As to why you're getting the "accessor must be more restrictive" error, is `Summation` really public? Without an explicit cast, it's not there at all. With an explicit cast, it can *only* be public. Interface members can only be public, and it can only be accessed *as* a member of an interface. So I suppose that interface access rules apply. See what the compiler says about this: `interface IFoo { int Bar { get; protected set; } }`. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:41
  • @EdPlunkett *'IFoo.Bar.set': accessibility modifiers may only be used on accessors in an interface* – samus Jun 14 '17 at 14:45
  • 1
    Your last error, regarding `this.Summation`, is easy: The declared type of `this` is `Calculator2`. That's true everywhere, with all that that implies, even inside the body of a method that explicitly implements a member of an interface. Fair enough; presumably you want to be able to use non-interface members of your class to do whatever the method needs to do. The alternative would require casting `this` to its own type, which would be odd. tl;dr: This will compile: `((IArithmetic2)this).Summation = x + y;` – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:46
  • Yep. And your class is constrained by that same rule when implementing an interface member explicitly. However, the fact that it's a different error message in that case makes me worry that I'm missing something deeper here. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:47
  • We'll if you put some/any/all of your comments into an answer I'll accept it. – samus Jun 14 '17 at 14:51
  • I'm trying to google this and coming up with nothing, so all I've got here is pure reason and throwing curveballs at the compiler to see what sticks. Hence I'm reluctant to post an answer because I've got nothing authoritative. Also, no doubt there are nine duplicates on SO that the search engine will never find in a million years, but some six figure guy will be crawling up my a** about the moment I submit the answer. There's probably some computer science term for it that I've never heard of. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:51
  • Anyway I'll give it an hour and if nobody's flagging you as a duplicate by then I'll go ahead. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 14:52
  • 1
    @EdPlunkett heh... ok well you've helped me a lot anyway, so thanks. – samus Jun 14 '17 at 14:52
  • 1
    @EdPlunkett When retrofitting existing classes with interfaces, this "explicit notation" will cause existing Property references to break (figured to report my finding). – samus Jun 14 '17 at 16:28
  • 1
    What'd you'd do in that case is duplicate the property and make one a wrapper around the other: `int IArithmetic2.Summation { get => Summation; set => Summation = value; } public int Summation { get; set; }`. Neither one hides the other, because one is visible only via a reference to `IArithmetic2`, and the other is only visible via a reference to `Calculator2`. – 15ee8f99-57ff-4f92-890c-b56153 Jun 14 '17 at 17:00

0 Answers0