Подтвердить что ты не робот

Преобразование производного класса в базовый класс

Я пытаюсь обновить свою память, но не могу найти ответы с Google.

public class BaseClass
{
    public virtual void DoSomething()
    {
        Trace.Write("base class");
    }
}

public class DerivedClass : BaseClass
{
    public override void DoSomething()
    {
        Trace.Write("derived class");
    }
}

Если я создаю экземпляр производного класса, как его преобразовать в базовый класс, так что, когда вызывается DoSomething(), он использует только метод базового класса?

Динамическое приведение по-прежнему вызывает переопределенный метод производного класса:

DerivedClass dc = new DerivedClass();

dc.DoSomething();

(dc as BaseClass).DoSomething();

Вывод: "производный класс"

4b9b3361

Ответ 1

Вы не можете - это полностью преднамеренно, так как это то, что полиморфизм. Предположим, что у вас есть производный класс, который обеспечивает определенные предварительные условия для аргументов, которые вы передаете переопределенному методу, чтобы поддерживать целостность... вы не хотите, чтобы обойти эту проверку и повредить ее внутреннюю целостность.

Внутри самого класса вы можете не виртуально вызывать base.AnyMethod() (независимо от того, какой метод вы переопределяете или нет), но это хорошо, потому что сам класс решает потенциально разрешить его целостность - по-видимому, он знает, что он делает.

Ответ 2

Хотя это звучит иррационально, но работает

 DerivedClass B = new DerivedClass();

BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));

Ответ 3

Вы абсолютно МОЖЕТЕ (вызвать базовый метод), просто прочитайте о полиморфизме:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism

Пример:

public class BaseClass
{
    public void DoWork() { }
    public int WorkField;
    public int WorkProperty
    {
        get { return 0; }
    }
}

public class DerivedClass : BaseClass
{
    public new void DoWork() { }
    public new int WorkField;
    public new int WorkProperty
    {
        get { return 0; }
    }
}

И как это назвать:

DerivedClass B = new DerivedClass();
B.DoWork();  // This calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // This calls the old method.

Ответ 4

Попробуйте использовать new keywor вместо override Насколько я знаю, это должно позволить это желаемое поведение. Я не совсем уверен в этом, поэтому, пожалуйста, не обвиняйте меня, если я ошибаюсь!

public class BaseClass
{
    public virtual void DoSomething()
    {
        Trace.Write("base class");
    }
}

public class DerivedClass : BaseClass
{
    public new void DoSomething()
    {
        Trace.Write("derived class");
    }
}

Ответ 5

Решения с new вместо override ломают полиморфизм. Недавно я пришел к одной и той же проблеме и реализовал ее следующим образом. Мое решение имеет следующие преимущества:

  • virtual и override остается на месте;
  • name BaseClass не используется непосредственно в типе cast, поэтому, если я введу промежуточный MiddleClass в иерархию между BaseClass и DerivedClass, который также реализует DoSomething(); то реализация MiddleClass не будет пропущена.

Это реализация:

public class BaseClass
{
    public virtual void DoSomething()
    {
        Trace.Write("base class");
    }
}

public class DerivedClass : BaseClass
{
    public override void DoSomething()
    {
        Trace.Write("derived class");
    }

    public void BaseDoSomething()
    {
        base.DoSomething();
    }
}

Использование:

    DerivedClass dc = new DerivedClass();

    dc.DoSomething();

    dc.BaseDoSomething();