Переопределение (приведение)

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

abstract class AbsBase
{
   private int A;
   private int B;
   private int C;
   private int D;
}

class Imp_A : AbsBase
{
   private List<int> E;
}


class Imp_B : AbsBase
{
   private int lastE;
}

Как правило, я буду приводить от Imp_A -> Imp_B, и я хочу, чтобы последним значением в списке E было «LastE». Кроме того, что, если бы было три или более классов реализации (например, «Зарплата», «Почасовая работа», «Консультант» и «Бывшие сотрудники»).

Независимо от того, является ли это архитектурно обоснованным (я не могу описать все приложение и быть кратким), возможно ли это?

Я собирался написать преобразователь, но, насколько я понимаю, преобразователь создаст новый объект класса Imp_B, который мне не нужен, потому что «сотрудник» будет только одним из вариантов в любой момент времени.

-Девин


person DevinB    schedule 07.04.2009    source источник


Ответы (2)


Вы должны реализовать явный или неявный оператор.

class Imp_A : AbsBase
{
   public static explicit operator Imp_B(Imp_A a)
   {
      Imp_B b = new Imp_B();

      // Do things with b

      return b;
   }
}

Теперь вы можете сделать следующее.

Imp_A a = new Imp_A();
Imp_B b = (Imp_B) a;
person Daniel Brückner    schedule 07.04.2009
comment
Имейте в виду, что это (очевидно) действительно создаст совершенно новый объект Imp_B. - person mqp; 07.04.2009
comment
Это идеально. Но, как упоминает Маквандер, это новый объект, которого я считаю неизбежным. Но означает ли это, что a не будет GC'ирован, пока он не выйдет из области видимости, даже если я больше никогда не буду его использовать (как Imp_A)? - person DevinB; 07.04.2009
comment
Да, он будет собран только в том случае, если он выйдет за рамки и у вас больше не будет ссылок на него. - person Daniel Brückner; 07.04.2009
comment
Просто обновление явного и неявные ссылки. - person Joao Coelho; 27.04.2016
comment
Я нашел это важным в MSDN: В целом, операторы неявного преобразования никогда не должны генерировать исключения и никогда не терять информацию, чтобы их можно было безопасно использовать без ведома программиста. Если оператор преобразования не соответствует этим критериям, он должен быть помечен как явный. - person Rekshino; 24.10.2018

Я бы посоветовал вам написать Imp_B следующим образом, если это возможно:

class Imp_B : Imp_A
{
    private int A;
    private int B;
    private int C;
    private int D;
    private int lastE { get { return this.E.Last(); } }
}

Если вы не можете на самом деле получить от ImpB, вы не сможете «обращаться» с объектом ImpA как с ImpB прозрачно, как вам хотелось бы, потому что они просто не являются одним и тем же в памяти. Итак, реализуйте явное преобразование.

person mqp    schedule 07.04.2009
comment
Кроме того, эти классы будут намного сложнее, с определенными переменными, которые являются эксклюзивными для каждого. А затем некоторые переменные (например, E), которые напрямую связаны, но не обязательно совпадают. - person DevinB; 07.04.2009