1

I have an interface which has a property with public get and protected set.

Yet when I implement this in my class i get an error saying it must be public.

My interface looks like this:

public interface ISegment
{
    INode NodeA { get; protected set; }
    INode NodeB { get; protected set; }
    public sealed void SetNodeA(INode node) => NodeA = node;
    public sealed void SetNodeB(INode node) => NodeB = node;
}

My class Segment : ISegment has the properties declared like this:

[SerializeField]
protected Node _nodeA;
public INode NodeA
{
    get => _nodeA;
    protected set => _nodeA = value as Node;
}

[SerializeField]
protected Node _nodeB;
public INode NodeB
{
    get => _nodeB;
    protected set => _nodeB = value as Node;
}

And i get this error:

'Segment' does not implement interface member 'ISegment.NodeA.set'
'Segment' does not implement interface member 'ISegment.NodeB.set'

What am i misunderstanding here?

WDUK
  • 1,412
  • 1
  • 12
  • 29

1 Answers1

1

Do it like this

    public interface ISegment
    {
        INode NodeA { get; protected set; }
        INode NodeB { get; protected set; }
        public sealed void SetNodeA(INode node) => NodeA = node;
        public sealed void SetNodeB(INode node) => NodeB = node;
    }

    public class MyClass : ISegment
    {
        private Node _nodeA;
        private Node _nodeB;

        INode ISegment.NodeA
        {
            get => _nodeA;
            set => _nodeA = value as Node;
        }

        INode ISegment.NodeB
        {
            get => _nodeB;
            set => _nodeB = value as Node;
        }

        private void Do(INode node)
        {
            if(node == NodeA) { } // Error
            if(node == _nodeA) { } // Warning "Possibly unintended reference comparison"
            if (node == ((ISegment)this).NodeA) { } // OK
        }
    }

but the Question is, why do you want that? Why protected set?

You can do it like this also. (Not helps here because of default implementation in the interface)


    public interface IFoo
    {
        public string Bar { get; }
    }

    public class Bubu : IFoo
    {
        public string Bar { get; protected set; }
    }

Update: Edited the code to show more exactly, how to access the properties

  • Not sure i see a difference here? Your property isn't even declared public in the class? As for why, because i only want derived classes to access it, everything else has to use the method. – WDUK Apr 22 '22 at 08:48
  • This is explicit interface property implementation. You can access the getter like normal public property but not the setter – Demetrius Axenowski Apr 22 '22 at 08:50
  • I'm confused how your first code example is any different to mine other than not declaring the setter modifier which makes it look private in your case which isn't what i wanted. – WDUK Apr 22 '22 at 08:56
  • 1
    AFAIK you can't access protected interface members within a implementing class. – Gabriel Apr 22 '22 at 08:56
  • Ah so it has to be public ? Damn thats annoying. Seems like a new access modifier is needed for this grey zone. – WDUK Apr 22 '22 at 08:57
  • I added some example to show how it works. You have to cast to `IFoo` to be able to access the property in the first example – Demetrius Axenowski Apr 22 '22 at 09:00
  • Or maybe you could create an abstract base class that provides the protected setter. – Gabriel Apr 22 '22 at 09:02
  • @DemetriusAxenowski Are you sure that the protected setter can be accessed in this way? – Gabriel Apr 22 '22 at 09:04
  • @DemetriusAxenowski why would you need to cast if you already derive from the interface? – WDUK Apr 22 '22 at 09:04
  • protected setter makes only sense, if you want to inherit from that class. So yes, in derived classes – Demetrius Axenowski Apr 22 '22 at 09:06
  • @DemetriusAxenowski yeah but it already is derived, i said `Segment : ISegment` so the cast is unusual to me. – WDUK Apr 22 '22 at 09:07
  • @WDUK I don't want it, I have to. Thats because of the `protected set`. You can not implement it in "normal" way. You have to do it like my example shows – Demetrius Axenowski Apr 22 '22 at 09:08
  • Also it didn't work for me i get a new error `Modifier public is not valid for this item` – WDUK Apr 22 '22 at 09:08
  • Once again, why declare the setter as protected in the interface? Here is a question about protected and interfaces https://stackoverflow.com/questions/516148/why-cant-i-have-protected-interface-members – Demetrius Axenowski Apr 22 '22 at 09:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244102/discussion-between-demetrius-axenowski-and-wduk). – Demetrius Axenowski Apr 22 '22 at 09:11
  • The setter is there because the interface has default implementation. So i don't need to declare the `public` aspect of the property because the cast does it for me? Thats kind've weird. – WDUK Apr 22 '22 at 09:12