开发者

C# Explicit Operators and Inheritance

I'm sure this is a stupid question, but why does开发者_开发百科 the following code not call the explicit operator for the cast on the child class 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 };
    }
}

then:

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

Produces the output: false, false

Is my only option to write functions on each class to take the place of the explicit operator functions?


why does the following code not call the explicit operator for the cast on the child class MyBool?

Because the operator functions are static, hence also non-virtual and thus their target is resolved at compile time rather than runtime. This is the expected behaviour.

If you want to have polymorphic conversion operators you can call virtual functions inside the operators:

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


Operators are overloaded rather than overridden - in other words, the choice about which implementation to use is made at compile-time. The compiler only knows about T as DataType, so it calls the operator in DataType.

One option would be to remove the operator from MyBool, but add a virtual method in DataType, allowing for polymorphic behaviour:

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

Note that this won't work for the conversion from bool to a DataType, as in that case we don't have any information about which subtype of DataType you actually want to create.

(Side-note: your code would be easier to follow if you used the normal .NET naming conventions.)


Here's a garbage solution for you:

replace: bool Value = (bool)T;

with: bool Value = (bool)(T as MyBool);

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜