显式运算符重载+继承

时间:2012-06-17 18:25:51

标签: c# casting polymorphism operator-overloading

我一直在考虑解决问题的方法,但我不确定它是否会起作用。

假设我们有一个名为A的基类和3个子类B,C和D.

        A
        ^
-----------------
|       |       |
B       C       D

我们还有三个类X,Y和Z。

在我的系统对象类型B,C,D作为类型A传递,通常我必须将类型B,C,D的对象转换为对象X,Y或Z(这不是演员,我手动转换因为它们完全不同所以。)

因此,要将对象类型A转换为类型X,Y或ZI需要首先检查子类型,然后使用有关A对象的某些操作的结果初始化X,Y或Z对象,具体取决于子类型。

我想过将一个显式的强制转换操作从A重载到X,Y或Z只是做我转换它时所做的相同的过程,但后来我想...是否可以使用polimorfism并重载强制转换从B,C和D中以某种方式,当我添加一个新的AI子类型时,不需要更改A的强制转换代码?(只需将显式强制转换添加到新的子类型中)

我希望如果有什么令人困惑的话,我已经非常好地解释了自己。

注意:我将为X,Y,Z添加一个强制转换

3 个答案:

答案 0 :(得分:3)

假设X,Y和Z派生自一个普通类型T,在A中声明一个抽象转换方法

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

并在B中覆盖它以返回X,在C中返回Y并在D中返回Z.这样每种类型都负责返回其自己的转换类型,并且在A中没有更改新类型已添加。

答案 1 :(得分:2)

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

当您知道该类为B时,(通过ConvertToX,因为X Convert()无法覆盖object Convert()),这会让您获得强类型结果object当你只知道它是A时。由于显式转换只能基于您正在使用的变量的静态类型发生,因此使用强制转换并不是一种很好的方法,就像您提出的那样。


(@ svick在我之前的代码中指出了一个主要缺陷,如下所示:如果你只知道对象是A而不是{{{}},那么你就不能轻易做任何事情。 1}}。如果你有任何用处,我会把它保存在这里:)

A<T>

如果你有一个可以转换为多种类型的类型,你可以这样做:

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

或者:

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

答案 2 :(得分:2)

您可以让类型为A的强制转换操作符调用A实例的虚拟(或抽象?)实例方法,并为A的每个子类重写该方法。 XYZ应该来自此解决方案的共同基类,因此强制转换运算符可以将该基类作为结果类型。

public abstract class A
{
    protected abstract W ConvertToW();

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

在此示例中,WXYZ的基类。