C#显式运算符和继承

时间:2011-06-06 12:06:21

标签: c# operator-overloading

我确定这是一个愚蠢的问题,但为什么下面的代码不会为子类MyBool上的强制转换调用显式运算符?

public class DataType
{
    public static explicit operator bool(DataType D)
    {
        return false;
    }

    public static explicit operator DataType(bool B)
    {
        return new DataType();
    }
}

public class MyBool : DataType
{
    public bool Value;

    public MyBool()
    {
        Value = false;
    }

    public static explicit operator bool(MyBool B)
    {
        return B.Value;
    }

    public static explicit operator MyBool(bool B)
    {
        return new MyBool() { Value = B };
    }
}

然后:

List<DataType> Types = new List<DataType>();

Types.Add(new MyBool() { Value = true });
Types.Add(new MyBool() { Value = false });

foreach (DataType T in Types)
{
    bool Value = (bool)T;
    MessageBox.Show(Value.ToString());
}

生成输出:false,false

我唯一的选择是在每个类上编写函数来代替显式运算符函数吗?

3 个答案:

答案 0 :(得分:16)

  

为什么以下代码不会为子类MyBool上的强制转换调用显式运算符?

因为运算符函数是static,因此也是非virtual,因此它们的目标在编译时而不是运行时解析。这是预期的行为。

如果你想拥有多态转换操作符,你可以在操作符中调用虚拟函数

public abstract class DataType
{
    public static explicit operator bool(DataType D)
    {
        return D.DoCastToBool();
    }

    public static explicit operator DataType(bool B)
    {
        // We haven’t got an instance of our class here.
        // You can use a factory method pattern to emulate virtual constructors.
    }

    protected abstract bool DoCastToBool();
}

答案 1 :(得分:2)

运算符重载而不是重写 - 换句话说,选择使用哪个实现在编译时。编译器只知道TDataType,因此它在DataType中调用运算符。

一种选择是从MyBool中删除运算符,但在DataType中添加虚拟方法,允许多态行为:

public class DataType
{
    public static explicit operator bool(DataType D)
    {
        // TODO: Decide how you want to handle null references
        return D.ToBoolean();
    }

    protected virtual bool ToBoolean()
    {
        return false;
    }
}

public class MyBool : DataType
{
    // ...

    protected override bool ToBoolean()
    {
        return Value;
    }
}

请注意,此不会适用于从boolDataType的转换,因为在这种情况下,我们没有关于{的哪个子类型的任何信息{1}}你真的想要创建。

(旁注:如果您使用正常的.NET命名约定,那么您的代码将更容易理解。)

答案 2 :(得分:-1)

这是给您的垃圾解决方案:

替换:bool Value = (bool)T;

具有:bool Value = (bool)(T as MyBool);