Page 1 of 1

When Implicit Casts Cause Problems. Rate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=329879&amp;s=6361cb156ee07b77cb0ca4832ac475ab&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

• MrCupOfT

Reputation: 2298
• Posts: 9,535
• 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)

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

 .related ul { list-style-type: circle; font-size: 12px; font-weight: bold; } .related li { margin-bottom: 5px; background-position: left 7px !important; margin-left: -35px; } .related h2 { font-size: 18px; font-weight: bold; } .related a { color: blue; }