覆盖(强制类型转换)

14

如果我有一个基类和两个派生类,并且我想手动实现在这两个派生类之间的转换,是否有方法可以实现?(使用C#)

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 类的新对象,但我不需要这样做,因为“employee”在任何时候都只是其中一种选项。
-Devin
2个回答

30

您必须实现显式隐式操作符。

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;

1
请记住,这将(显然)确实创建一个全新的Imp_B对象。 - mqp
太好了。但是,正如mquander所提到的,这是一个新对象,我认为这是不可避免的。但这是否意味着“a”在作为Imp_A时再也没有被使用,即使我再也不使用它,它也不会被GC回收直到超出范围? - DevinB
是的,只有当它超出范围并且您不再持有任何引用时,它才会被收集。 - Daniel Brückner
1
只是更新一下 显式隐式 链接。 - Joao Coelho
我在MSDN上发现了一个重要的提示:通常情况下,隐式转换操作符不应该抛出异常,也不应该丢失信息,以便可以在程序员不知情的情况下安全使用。如果一个转换操作符不能满足这些标准,那么它应该被标记为显式。 - Rekshino

2
如果可能的话,我建议您将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对象,因为它们在内存中并不是同一个东西。因此,请实现显式转换。

此外,这些类将会更加复杂,具有各自独特的某些变量。还有一些变量(如E)是直接相关的,但不一定相同。 - DevinB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接