0

I learned Java before I learned C#, and I've typically found C# to give me more freedom as a programmer than Java does, and that's why I really like it. I'm a bit baffled though by a problem I'm currently running into concerning access modifiers. Say I have a class.

public class Foo
{
    public virtual int SomeProperty { get; protected set; }
}

And another derived class.

public class Bar : Foo
{
    public override int SomeProperty { get; set; }
}

The compiler throws an error saying

CS0507 'Bar.SomeProperty.set': cannot change access modifiers when overriding 'protected' inherited member 'Foo.SomeProperty.set'

Why is this a thing? In Java, I am allowed to expand access to base members by overriding them in derived classes, just not the other way around. (Read: You cannot restrict base members further in derived classes) Am I missing something here or doing something stupid I don't know about?

I know I could declare public new SomeProperty { get; set; }, but that's not what I want. I want polymorphism here.

Please enlighten me. Thank you.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Nic Estrada
  • 480
  • 5
  • 16
  • Does this answer your question? [Why can't we change access modifier while overriding methods in C#?](https://stackoverflow.com/questions/6236909/why-cant-we-change-access-modifier-while-overriding-methods-in-c) – TheBatman Feb 14 '20 at 18:00
  • @TheBatman Sort of? It does address the same problem, but the answer is essentially "IMO there's no use case for it" I definitely have a use case. I would like two different derived classes from the base. One of them with public setters, one of them with protected setters. In Java, this is allowed. In C# it's not. I can't imagine the C# developers left it out just because they personally couldn't figure out a use case. There's got to be a more substantial reason. – Nic Estrada Feb 15 '20 at 21:07

1 Answers1

1

You could hide the base class property and provide a setter there. In essence, the signature of the class will become exactly how you want it to be, albeit as a sort of workaround.

public class Bar : Foo
{
    public new int SomeProperty
    {
        get => base.SomeProperty;
        set => base.SomeProperty = value;
    }
}
Jesse de Wit
  • 3,867
  • 1
  • 20
  • 41
  • "I know I could declare public new SomeProperty { get; set; }, but that's not what I want. I want polymorphism here." The problem is that if I have a reference to a Foo object that is actually a Bar object, it's not the same property any more. It kills the JSON serialization that I'm using. – Nic Estrada Feb 17 '20 at 17:30
  • Can you elaborate on what happens when you JSON serialize the object when you have hidden the property? What if you serialize it as Foo, and what if you serialize it as Bar? – Jesse de Wit Feb 18 '20 at 09:34
  • For all other cases it is basically the same as polymorphism. Access the object as `Foo` and you do not have a setter. Access the object as `Bar`, and you do have a setter. – Jesse de Wit Feb 18 '20 at 09:35
  • Please ignore my previous comment. I had a different problem plaguing the Serialization that merely made it look like this was the problem. This is a fine workaround. I'm just dense sometimes. – Nic Estrada Feb 19 '20 at 16:29