4

我一直在想一种方法来解决我遇到的问题,但我不确定它是否会起作用。

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

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

我们也有 X、Y 和 Z 三个类。

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

因此,要将 Object 类型 A 转换为 X、Y 或 Z 类型,需要先检查子类型,然后根据子类型对 A 对象进行一些操作的结果来初始化 X、Y 或 Z 对象。

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

如果有什么令人困惑的地方,我希望我已经正确地解释了自己。

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

4

3 回答 3

3

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

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

并在 B 中覆盖它以返回 X,在 C 中返回 Y,在 D 中返回 Z。这样,每种类型都负责返回其自己的转换类型,并且当新类型出现时,无需在 A 中进行任何更改添加。

于 2012-06-17T18:35:18.713 回答
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();
}

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


(@svick 指出了我之前的代码中的一个主要缺陷,如下所示,如果你只知道对象是 an A,而不是 an ,你就不能轻易地用它做任何事情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();
    }
}

或者:

class B : A, IConvertible<X>, IConvertible<Y>
{
    X IConvertible<X>.Convert()
    {
        throw new NotImplementedException();
    }
    Y IConvertible<Y>.Convert()
    {
        throw new NotImplementedException();
    }
}
于 2012-06-17T18:33:12.567 回答
2

您可以让类型转换运算符A调用实例的虚拟(或抽象?)实例方法,A并为A. XY并且Z应该派生自此解决方案的相互基类,因此强制转换运算符可以将该基类作为结果类型。

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

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

在此示例中,是和W的基类。XYZ

于 2012-06-17T18:33:22.787 回答