Wywołanie bazowej metody wirtualnej w klasie pochodnej.

0

Mała łamigłówka. Jak wywołać w metodzie ToString() w klasie Kwadrat nie metodę bazową (jak w Prostokat), ale konkretną implementację w drzewie dziedziczeń, czyli w tym wypadku z "dziadka", t.j. Object.ToString().
Kod w takiej postaci jak poniżej nie działa, bo odwołanie do (Object).ToString() powoduje rekurencję.
Chciałbym, żeby Kwadrat.ToString() zwrócił mi tekst:
Kwadrat o boku x = 5
Dzięki za sugestie.

   public class Prostokat
    {
        public double BokX { get; set; }
        public double BokY { get; set; }
        public Prostokat(double x, double y) { this.BokX = x; this.BokY = y; }
        public override string ToString() => base.ToString() + $" o bokach: x = {BokX}; y = {BokY}";
    }

   public class Kwadrat : Prostokat
    {
        public Kwadrat(double x) : base(x, x) { }
        public override string ToString() => (Object)ToString() + $" o boku: x = {BokX}";
    }

2

czyli chcesz nadpisać metodę, ale jednak nie?

public class Prostokat
{
    public double BokX { get; set; }
    public double BokY { get; set; }
    public Prostokat(double x, double y) { this.BokX = x; this.BokY = y; }
    public override string ToString() => base.ToString() + $" o bokach: x = {BokX}; y = {BokY}";

    public string ToStringHack() => base.ToString();
}

public class Kwadrat : Prostokat
{
    public Kwadrat(double x) : base(x, x) { }

    public override string ToString()
    {
        return $"{ToStringHack()} o boku: x = {BokX}";
    }
}

PrzestrzenNazewnicza.Kwadrat o boku: x = 15

1

Żeby ten hack jeszcze protected był...

Najprościej to chyba jednak:

public override string ToString() => $"{nameof(Kwadrat)} o boku: x = {BokX}";
0

@somekind: Dziękuję

1

czyli nadal nie ma w c# odpowiednika :: z c++? :(

1

może powinieneś przemyśleć czy to co faktycznie chcesz uzyskać ma sens i czy nie ma lepszego rozwiązania?

jeżeli faktycznie chcesz mieć ToString z objecta, a nie jest to po prostu jakiś przykład, no to masz wiele sposobów na wyciągnięcie tych informacji typu nawet

this.GetType().*

0

@WeiXiao:
Myślałem, że pytanie jest proste i Twoja odpowiedź z użyciem ToStringHack() jest jakimś rozwiązaniem problemu, ale chyba nie zrozumiałem propozycji wyciągnięcia informacji o drzewie dziedziczenia poprzez GetType(). Więc jeszcze taki sobie przykład o co chodzi.
Co miałbym wpisać zamiast "co_tu", by osiągnąc zamierzony efekt?

class A {
    public virtual string Slowo() => "Wlazł ";
}
class B : A {
    public override string Slowo() => "kotek ";
}
class C : B {
    public override string Slowo() => "na płotek ";
}
class D : C
{
    public override string Slowo() => "i mruga";
}

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            D piosenka = new();
            Console.WriteLine(piosenka.GetType().co_tu + piosenka.Slowo);
            // chciałbym np. wyświetlić napis: "kotek i mruga"
            // albo: "Wlazł i mruga"
            // albo: "Wlazł na płotek"
        }
    }
}
2

Wydaje mi się ze nie przesłaniać tylko nadpisywać trzeba metody np. tak:

    class A
    {
        public virtual string Slowo() => "Wlazł ";
    }
    class B : A
    {
        public new string Slowo() => "kotek ";
    }
    class C : B
    {
        public new string Slowo() => "na płotek ";
    }
    class D : C
    {
        public new string Slowo() => "i mruga";
    }

    class Program
    {
        static void Main(string[] args)
        {
            D piosenka = new D();

            Console.WriteLine(((B)piosenka).Slowo() + piosenka.Slowo());
            Console.WriteLine(((A)piosenka).Slowo() + piosenka.Slowo());
            Console.WriteLine(((A)piosenka).Slowo() + ((C)piosenka).Slowo());

            Console.ReadLine();
            // Wyniki w konsoli:
            // "kotek i mruga"
            //  "Wlazł i mruga"
            //  "Wlazł na płotek"
        }
    }
4

Coraz bardziej wygląda mi to na problem XY albo przynajmniej próbę używania dziedziczenia tam, gdzie nie ma ono sensu.

0

Fajnie. Dziękuję za podpowiedź @Varran
Właśnie o to chodziło. Zastanawiałem się, czy gdy zastąpię override przez new, to czy zrobię coś takiego.
Zrobię, tyle że zamiast po metodzie wirtualnej muszę polecieć w pętli po interfejsie. Działa :-)

interface IMelodia { public string Slowo(); }
class A : IMelodia
class B : A, IMelodia
class C : B, IMelodia

           IMelodia[] szafaGrajaca = {
                new A(),
                new B(),
                new C(),
                new D() };
            foreach (IMelodia melodia in szafaGrajaca)
                Console.WriteLine(melodia.Slowo());

1 użytkowników online, w tym zalogowanych: 0, gości: 1