F# Casting

Conversion is a process of converting type of a value to the other required type. It can be primitive or object type. F# provides conversion operators for arithmetic conversions between various primitive types, such as between integer and floating-point types.

The integral and char conversion operators have checked and unchecked forms;

  • The floating-point operators and the enum conversion operator do not.
  • The unchecked forms are defined in the Microsoft.FSharp.Core.Operators and the checked forms are defined in the Microsoft.FSharp.Core.Operators.Checked.
  • The checked forms check for overflow and generate a runtime exception if the resulting value exceeds the target type's limits.

Let's consider the following example in which the int is cast to the byte.

let x : int = 17
let y : byte = byte x

Console.WriteLine("x: {0}", x)
Console.WriteLine("y: {0}", y)

Each of these operators has the same name as the name of the destination type. For example, in the above code, in which the types are explicitly annotated, byte appears with two different meanings. The first occurrence is the type and the second is the conversion operator.

Casting Object Types

Conversion between types in an object hierarchy is fundamental to object-oriented programming. There are two basic types of conversions:

  • Upcasting
  • Downcasting


Upcasting means casting from a derived object reference to a base object reference. Such a cast is guaranteed to work as long as the base class is in the derived class's inheritance hierarchy.


Downcasting means casting from a base object reference to a derived object reference. It succeeds only if the object is an instance of the correct destination (derived) type or a type derived from the destination type.

F# provides operators for these types of conversions. The :> operator casts up the hierarchy, and the :?> operator casts down the hierarchy.

let value = 34
printfn "%A" value

// Upcast
let valueObj = value :> obj
printfn "%A" valueObj

// Downcast
let valueInt = valueObj :?> int
printfn "%A" valueInt

You can also use the upcast and downcast operators to perform such a conversion, as shown below.

type Shape() =  
     member this.Print()=  
       printfn "Shape"  
type Circle() =   
     inherit Shape()  
     member this.Print()=  
      printfn "Circle"  
let shape = new Shape()              
let circle : Circle = new Circle()  

let castIntoShape = upcast circle : Shape                 // upcasting   

let castIntoCircle = downcast castIntoShape : Circle      // downcasting