So we've got this class that reflects Yes / No.
Public NotInheritable Class YesNo Public Shared ReadOnly No As YesNo= New YesNo(False) Public Shared ReadOnly Yes As YesNo= New YesNo(True) Public ReadOnly Value As Boolean Protected Sub New(IsYes As Boolean) Me.Value = IsYes End Sub Shared Operator IsFalse(YN As YesNo) As Boolean Return not YN.Value End Operator Shared Operator IsTrue(YN As YesNo) As Boolean Return YN.Value End Operator Public Overrides Function ToString() As String Return If(Me.Value,"Yes","No") End Function Shared Operator =(yn0 As YesNo, yn1 As YesNo) As YesNo Return If(yn0.Value = yn1.Value,Yes,No) End Operator Shared Operator <>(yn0 As YesNo, yn1 As YesNo) As YesNo Return If( yn0.Value <> yn1.Value,Yes,No) End Operator Shared Operator And(yn0 As YesNo, yn1 As YesNo) As YesNo Return If( yn0 = No, No,yn1) End Operator Shared Operator Or(yn0 As YesNo, yn1 As YesNo) As YesNo Return If( yn0,Yes,yn1) End Operator Shared Operator xOr(yn0 As YesNo, yn1 As YesNo)As YesNo Return If( yn0 AndAlso yn1, No,(yn0 orelse yn1)) End Operator Shared Operator Not(yn0 As YesNo) As YesNo Return If( yn0= Yes,No,Yes) End Operator End Class
And simple code to try it out.
Module Module1 Sub Main() Dim Milk As YesNo = Yes Dim Coffee As YesNo = No If Not Coffee Then Console.WriteLine( Coffee) End Sub End Module
Ok let's now add a cast operator so that class can used where Boolean can be used.
So we add the following to the YesNo class, cos I using Option Strict On, which disables implicit narrowing conversions.
Shared Widening Operator CType(YN As YesNo) As Boolean Return YN.Value End Operator
The run the code again we get False
What's going on?
The are two basic types of Casting:-
Where there is a potential loss of data, this maybe because of difference in the number of bytes used.Double --> Byte
Where there is no loss of data.
These two types of casting can be utilised in two different ways:-
Where the coder explicitly writes the cast.operation.
Where the coder does explicitly write the cast operation, but the compiler allows the conversion.
Ok so why did we get the wrong output?
This is to do with method overloads, methods the have the same identifier names but different input parameter types.
Public Sub WriteLine(value As Boolean) Public Sub WriteLine(value As Object) Public Sub WriteLine(value As String) Public Sub WriteLine(format As String, ParamArray arg() As Object)
The compiler see the boolean version first, the object can be cast to a boolean. So uses it.
A simple fix
Is to use a different overload but which one and how?
We could use another cast.
I prefer to use the format string version.
As this doesn't involve another cast.