Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 580
Andy Avatar asked Jun 06 '11 12:06

Andy


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


2 Answers

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();
}
like image 170
Konrad Rudolph Avatar answered Sep 29 '22 15:09

Konrad Rudolph


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.)

like image 31
Jon Skeet Avatar answered Sep 29 '22 15:09

Jon Skeet