views:

184

answers:

3

How can I use DbCommand.ExecuteScalar from F#? It returns an obj which I need to convert to an int. I'm very new to F# and the casting I need to do is not clear.

let (stockid:uint32) = command.ExecuteScalar()

Compile Error: 
Type constraint mismatch. The type   obj is not compatible with type  uint32

Upcasting using :?> throws a runtime error.

+4  A: 

If you just say

let o : obj = ...
printfn "%s" (o.GetType().ToString())

what do you get? Is it indeed an int? (int32 or uint32 or what?)

The :?> operator is the correct downcast operator, but you need the types to match. After casting to the actual type, if you need to convert from one integral type to another, then use the corresponding function for the destination type, e.g.

let x : int = int myUnsignedInt  
// first 'int' is type, second is function to convert-to-int
Brian
Assuming it's int32, what's the proper way to cast object -> uint32? Do you go the C# route of object -> int32 (essentiall unbox) -> uint32 or is there a more idiomatic method in F#?
JaredPar
Turns out ExecuteScalar was returning an int64. Once the types matched everything worked. Thanks for the detailed answer and explanation of what was happening.
MikeW
A: 

If the Downcast (:?>) throws at runtime, you're not getting a unit32 as a return value from the Execute Scalar. You should be able to convert ...

let stockid : uint32 = unit32 command.ExecuteStalar()

But if you're getting something that can't be converted to an uint32, that will fail too.More on casting and converting here.

JP Alioto
A: 

Try casting it to an int32 instead of a uint32. ExecuteScalar returns an object of int32.

Robert Harvey