0

I wonder if something like this is possible in C#:

public class A
{
    public string Foo() { return "Foo"; }
}

public class B : A
{
    public string Bar() { return Foo(); }
}

public class C : B
{
    public new string B.Foo() { return "Bar"; } // Hide A.Foo in B
}

Main()
{
    C c = new C();
    Console.WriteLine(c.Bar()); // Want to get "Bar"
}

by public new string B.Foo() { return "Bar"; } I mean do something in C (without changing A or B) that has the equivalent result as if public new string Foo() { return "Bar"; } was implemented in B. So, hide a method FOR a base class OF a base further up the inheritance hierarchy.

matthias_buehlmann
  • 4,641
  • 6
  • 34
  • 76

1 Answers1

1

What you want is virtual, which allows you to override base behavior in the inheriting type.

public class A
{
    public virtual string Foo() { return "Foo"; }
}

public class B : A
{
    public virtual string Bar() { return Foo(); }
}

public class C : B
{
    public override string Foo() { return "Bar"; } // Hide A.Foo in B
}

This outputs "bar"

David L
  • 32,885
  • 8
  • 62
  • 93
  • no, without changing A or B. That's why I'm asking about method hiding, not overriding – matthias_buehlmann Aug 27 '21 at 17:41
  • 1
    You can do it without changing A or B _only if_ they were designed to make Foo "overridable" in a subclass. This is done by declaring the method `virtual`. Base classes must opt-in to overriding in C#. – David Browne - Microsoft Aug 27 '21 at 17:42
  • @DavidBrowne-Microsoft I don't want to override, I want to hide – matthias_buehlmann Aug 27 '21 at 17:43
  • Hiding only works on instances of the hiding type. `B b = new C(); b.Foo();` will run B's Foo if C only hides it. So you don't want to hide. What you describe is overriding, not hiding. – David Browne - Microsoft Aug 27 '21 at 17:44
  • No, I want to hide, but in B and not in C, by only editing C, so that `A a = new C(); a.Foo()` will return "Foo" but `B b = new C(); b.Foo()` will return "Bar" – matthias_buehlmann Aug 27 '21 at 17:47
  • @matthias_buehlmann the compiler simply does not allow this type of behavior. If you cannot modify base classes, a typical pattern might be the decorator or adapter pattern to override base behavior. But this is exactly what virtual enables...modifying behavior of the base type via the inheriting type. – David L Aug 27 '21 at 17:53
  • I mean, using reflection and unsafe code it's possible to replace complete nonvirtual methods in classes - so it's not reasonable to assume that what I want is possible somehow too. – matthias_buehlmann Aug 27 '21 at 18:01
  • 1
    It IS unreasonable, for the exact reasons you just gave. Reflection uses runtime apis and is not guaranteed by the compiler, which is what is currently restricting you. Furthermore, unsafe code is just that, unsafe. If you want to do this inside the parameters of safe, compile-time driven checking, it is simply not possible _per the compiler_ and virtual+override gives you a type-safe way to express the behavior. Otherwise, you have to wrap the instance. – David L Aug 27 '21 at 18:03