Explicit operator overloading + inheritance

I was thinking about how to solve the problem that I have, and I'm not sure if this will work or not.

Say we have a base class of subclass A and 3 of subclass B, C, and D.

A ^ ----------------- | | | BCD 

We also have three classes X, Y and Z.

In my system objects, type B, C, D is passed as type A, and usually I have to convert objects of type B, C, D to objects X, Y or Z (this is not casting, I manually convert them, because they are completely different).

Therefore, in order to convert the type of object A to type X, Y or ZI, you must first check the subtype, and then initialize the object X, Y or Z with the result of some operations on object A, depending on the subtype.

I thought about overloading the explicit operation from A to X, Y or Z, just doing the same process that I did when I converted them, but then I thought ... Is it possible to use polymorphism and overload casting from B, C and D in some way, that when I add a new AI subtype, I don’t need to change the cast code A? (just add explicit cast overload to the new subtype)

Hope I correctly explained that there is something confusing.

NOTE. I will add overload for X, Y, Z

+4
source share
3 answers

You can force a listing operator of type A call the virtual (or abstract?) Instance method of your instance of A and override it for each subclass of A X , Y and Z must be based on a reciprocal base class for this solution, so the translation operator can have this base class as a result.

 public abstract class A { protected abstract W ConvertToW(); public static explicit operator W(A a) { return a.ConvertToW(); } } 

In this example, W is the base class of X , Y and Z

+2
source

Assuming that X, Y, and Z are derived from a common type T, we declare an abstract method for converting to A

 public abstract class A { public abstract T Convert(); } 

and override it in B to return X to C to return Y and D to return Z. Thus, each type is responsible for returning its own converted type, and in no changes, a new type is added.

+3
source
 abstract class A { public abstract object Convert(); } class B : A { public override object Convert() { return ConvertToX(); } public X ConvertToX() { return new X(); } } void SomeMethod() { A o = new B(); var result = (X)o.Convert(); } 

This allows you to get a strongly typed result when you know that class B , (via ConvertToX , since X Convert() cannot override object Convert() ) and object when you know a A Since explicit conversions can only occur based on the static type of the variable you are using, there really is no good way to do this with casting, as you requested.


(@svick pointed out the main drawback of my previous code, which is below, that you cannot easily do anything with it if you only know object A , not A<T> . I will save it here if you use it :)

 interface IConvertible<out T> { T Convert(); } abstract class A { } abstract class A<T> : A, IConvertible<T> { public abstract T Convert(); public static explicit operator T(A<T> a) { return a.Convert(); } } class B : A<X> { public override X Convert() { // TODO implement this } } 

And if you have a type that can be converted to several types, you can do:

 class B : A<X>, IConvertible<Y> { public override X Convert() { throw new NotImplementedException(); } Y IConvertible<Y>.Convert() { throw new NotImplementedException(); } } 

Or:

 class B : A, IConvertible<X>, IConvertible<Y> { X IConvertible<X>.Convert() { throw new NotImplementedException(); } Y IConvertible<Y>.Convert() { throw new NotImplementedException(); } } 
+2
source

All Articles