Постоянное литье в суперкласс - PullRequest
5 голосов
/ 29 октября 2010

Если:

class Car : Automobile
{}

Я могу сделать:

Car toyota = new Car();
Automobile tauto = (Automobile)toyota;

, но если я сделаю tauto.GetType().Name, это все равно будет Автомобиль .

Можно ли выполнить приведение, чтобы тип был постоянно изменен на Автомобильный (без клонирования объекта)?

Проблема, которую я пытаюсь преодолеть, заключается в том, что в c # нет множественного наследования, и мне нужно объединить объекты (с одинаковой сигнатурой) из 2 служб в одном методе и вернуть один тип.

Ответы [ 5 ]

11 голосов
/ 29 октября 2010

Нет. Невозможно сделать это без создания нового автомобильного объекта.

Однако нет также причин делать это. Принцип подстановки Лискова гласит, что любой Car всегда должен обрабатываться точно так же, как Automobile, и пользователь не должен иметь никаких изменений в ожидаемом поведении.

Пока вы правильно проектируете иерархию классов, использование Car в качестве Automobile всегда должно быть вполне приемлемым.


Примечание: это часть того, почему использование Type.GetType() не является предпочтительным способом проверки типа. Гораздо безопаснее и лучше использовать is и в качестве ключевых слов в C #. Они вернут истину, если вы проверите, что tauto is Car.

0 голосов
/ 29 октября 2010

В некоторых случаях могут помочь дженерики. Если метод включает универсальный параметр, универсальный тип будет оцениваться как объявленный тип переданной ссылки, а не как тип переданного объекта. Например:

void Foo(T bar)

Если foo () вызывается с помощью (Control) someButton, типом «bar» будет Button, а типом T будет Control.

0 голосов
/ 29 октября 2010

Я не совсем уверен, что именно вы пытаетесь сделать, но, возможно, вы могли бы рассмотреть другой подход?Вместо того, чтобы пытаться объединить функциональность двух разных классов с помощью наследования, может быть, вы могли бы использовать композицию?

http://tiedyedfreaks.org/eric/CompositionVsInheritance.html

public class Service
{
    public virtual void DoSomething()
    {

    }
}

public class ServiceA : Service
{
    public override void DoSomething()
    {

    }
}

public class ServiceB : Service
{
    public override void DoSomething()
    {

    }
}

public class ServiceA_B : Service
{
    ServiceA serviceA = new ServiceA();
    ServiceB serviceB = new ServiceB();

    public override void DoSomething()
    {
        serviceA.DoSomething();
        serviceB.DoSomething();   
    }
}
0 голосов
/ 29 октября 2010

Ваш вопрос и то, что вы пытаетесь сделать, кажутся двумя разными вещами. Нет, вы не можете изменить базовый тип объекта. Но то, что вы, похоже, хотите сделать, это создать тип автомобиля с набором свойств, а не использовать подкласс. То, что вы могли бы сделать, это использовать вместо этого автомобильный завод.

public static class AutomobileFactory()
{
   public static Automobile CreateAutomobile(AutomobileType type)
   {
     ...   
   } 
}

Где AutomobileType - это перечисление. Для получения дополнительной информации Google C # Factory шаблон.

0 голосов
/ 29 октября 2010

Согласно MSDN , вы просто приводите ссылку к объекту, а не к базовому объекту.

...