Page 1 of 1

When Implicit Casts Cause Problems. Rate Topic: -----

#1 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,498
  • Joined: 29-May 08

Posted 24 September 2013 - 05:50 AM

When Implicit Casts Cause Problems.

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



Output No

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:-
  • Narrowing
    Where there is a potential loss of data, this maybe because of difference in the number of bytes used.Double --> Byte
  • Widening
    Where there is no loss of data.


These two types of casting can be utilised in two different ways:-
  • Explicit
    Where the coder explicitly writes the cast.operation.
        CType(myObject, Integer)
      
    

  • Implicit
    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.
Console.WriteLine(CType(Coffee, Object))



I prefer to use the format string version.
Console.WriteLine("{0}", Coffee)



As this doesn't involve another cast.

Is This A Good Question/Topic? 1
  • +

Page 1 of 1