Accessing hidden member through derived instance selects base class member

22 hours ago 1
ARTICLE AD BOX

Google's AI Overview states that:

In C#, if a derived class hides a base class member (using new) but the hiding member is inaccessible (e.g.private or protected in a different context), the compiler does not automatically fall back to the base member. Instead, it typically throws a compiler error (CS0122: "inaccessible due to its protection level") because the compiler sees the hidden member first and blocks access, even if the base member is public.

However, the following code compiles without error:

public class Base { private readonly int value = 42; public int Value => value; public Base() { } } public sealed class Derived : Base { private new int Value => throw new NotSupportedException(); } static void Main() { Base b = new(); int bValue = b.Value; Derived d = new(); int dValue = d.Value; Console.WriteLine($"bValue: {bValue}; dValue: {dValue}"); }

If Derived.Value is made public, then there is no compile-time error, but the NotSupportedException does get thrown, showing that the compiler does select the hiding member, when it is public.

I assume that this is an instance of Google AI getting it wrong, and that the compiler falling back to the accessible Base.Value when Derived.Value is inaccessible is the intended behavior. If that is the case, then other options such as applying an ObsoleteAttribute with error: true could still enforce not directly using Derived.Value through a Derived-typed instance, leaving the access modifier the same between Base and Derived.

My question is whether the compiler fallback is indeed by design, since the Google AI results explicitly indicated different behavior.

To be clear about what I'm trying to accomplish, I wanted to change the public API name of a base class property. The name has different meanings between the base and derived classes. There is no issue or conflict with naming when accessing the instance through the base class, and I want to expose the same value through a differently-named property in the derived class. My goal was to hide the base class property so that it is not mistakenly used incorrectly (misinterpreting/misunderstanding) when accessed through the derived class. The ObsoleteAttribute is sufficient for this, and this question is more for curiosity and clarity.

Read Entire Article