14

If I have a base class and two derived classes, and I want to implement the casting between the two derived classes by hand, is there any way to do that? (in 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;
}

Generally I'll be casting from Imp_A -> Imp_B and I want the last value in the E list to be the 'LastE'. Also, what if there were three or more implementation classes (such as Salary, Hourly, Consultant, and Former Employees.)

Regardless of whether this is architecturally sound (I can't describe the whole application and be concise) is it possible?

I was going to write a converter, except that to my understanding a converter will create a new object of the Imp_B class, which I don't need because the 'employee' will only be one of the options at any one time.

-Devin

DevinB
  • 8,231
  • 9
  • 44
  • 54

2 Answers2

30

You must implement a explicit or implicit operator.

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;
   }
}

Now you can do the following.

Imp_A a = new Imp_A();
Imp_B b = (Imp_B) a;
Stee
  • 970
  • 5
  • 9
Daniel Brückner
  • 59,031
  • 16
  • 99
  • 143
  • 1
    Keep in mind that this will (obviously) indeed create a whole new Imp_B object. – mqp Apr 07 '09 at 12:54
  • That's perfect. But, as mquander mentions, it's a new object, which I believe is unavoidable. But does this mean that "a" won't be GC'd until it falls out of scope, even though I never use it again (as an Imp_A)? – DevinB Apr 07 '09 at 12:57
  • Yes, it will get collected only if it falls out of scope and you do no longer hold any references to it. – Daniel Brückner Apr 07 '09 at 13:08
  • 1
    Just an update to the [explicit](https://msdn.microsoft.com/en-us/library/xhbhezf4(v=vs.140).aspx) and [implicit](https://msdn.microsoft.com/en-us/library/z5z9kes2(v=vs.140).aspx) links. – Joao Coelho Apr 27 '16 at 07:15
  • I found it important on MSDN: _In general, implicit conversion operators should never throw exceptions and never lose information so that they can be used safely without the programmer's awareness. **If a conversion operator cannot meet those criteria, it should be marked explicit**_. – Rekshino Oct 24 '18 at 13:45
2

I'd suggest you write Imp_B like this, if possible:

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(); } }
}

If you can't actually derive from ImpB, it's impossible for you to "treat" a ImpA object as an ImpB transparently the way you'd like, because they just aren't the same thing in memory. So, implement an explicit conversion.

mqp
  • 70,359
  • 14
  • 95
  • 123
  • Also, these classes will be much more complicated, with certain variables that are exclusive to each. And then certain variables (like E) which are directly related, but not necessarily the same. – DevinB Apr 07 '09 at 12:38