Reputation: 5575
I have been thinking about a way solve a problem I have and I'm not sure whether it will work or not.
Say we have a base class called A and 3 subclass B,C and D.
A
^
-----------------
| | |
B C D
Also we have three classes X, Y and Z.
On my system objects type B,C,D are passed as type A and usually I have to convert the Objects of type B,C,D to either objects X,Y or Z (That's not a cast, I manually convert them since they are totally different).
Therefore, to convert an Object type A to a type X, Y or Z I need to check the subtype first and then initialize a X, Y or Z Object with the result of some operations about the A Object depending on the subtype.
I thought about overloading an explicit cast operation from A to X, Y or Z just doing the same process I was doing when I converted them, but then I thought... Would it be possible to use polimorfism and overload the cast from B,C and D in some way that when I add a new subtype of A I do not need to change the cast code of A?(Just add the explicit cast overload to the new subtype)
I hope I have explained myself properly sorry if there is something confusing.
NOTE: I will add a cast overload for X,Y,Z
Upvotes: 5
Views: 2116
Reputation: 112392
Assuming that X, Y and Z derive from a common type T, declare an abstract conversion method in A
public abstract class A
{
public abstract T Convert();
}
and override it in B to return an X, in C to return a Y and in D to return a Z. This way each type is responsible to return its own converted type and there is no change to make in A when a new type is added.
Upvotes: 3
Reputation: 56536
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 lets you have a strongly-typed result when you know that class is B
, (through ConvertToX
, since X Convert()
can't override object Convert()
) and an object
when you only know it's an A
. Since explicit conversions can only happen based on the static type of the variable you're using, there's not really a good way to do this using casting, like you asked.
(@svick pointed out a major flaw in my previous code, which is below, which is that you can't easily do anything with it if you only know the object is an A
, not an A<T>
. I'll keep it here in case you have any use for 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 multiple types, you could 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();
}
}
Upvotes: 2
Reputation: 20730
You can have your cast operator for type A
call a virtual (or abstract?) instance method of your A
instance and override that for each subclass of A
. X
, Y
and Z
should derive from a mutual base class for this solution, though, so the cast operator can have that base class as a result type.
public abstract class A
{
protected abstract W ConvertToW();
public static explicit operator W(A a)
{
return a.ConvertToW();
}
}
In this example, W
is a base class of X
, Y
and Z
.
Upvotes: 2