Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic cast to Interface

Tags:

f#

According to the post http://cs.hubfs.net/forums/thread/3616.aspx, I need to use a function like the following to cast an object to an interface, I have run a test, this is still true, the bug of :?> is still not fixed.

let cast<'a> o = (box o) :?> 'a
let ci = {  new Customer(18, Name = "fred") with
                override x.ToString() = x.Name 
            interface ITalk with
                member x.Talk() =
                    printfn "talk1111111" }

let italk = cast<ITalk> ci

if not (italk = null) then
    italk.Talk()

Is there a more elegant way to write the above code. I am thinking to create another operator to replace :?>, but I can not get the generic type parameter passed in like the :?>

like image 777
Fred Yang Avatar asked Dec 21 '25 23:12

Fred Yang


1 Answers

Your cast function does not behave like the C# as operator - if the object can't be cast to the specified type, it will throw an exception rather than returning null. Therefore, checking to see if italk = null accomplishes nothing. If you want to make the cast function return null when the cast fails instead of throwing an exception, you could write it like this:

let cast<'a when 'a : null> o =
    match box o with
    | :? 'a as output -> output
    | _ -> null

However, this will only work on nullable types, which does not include structs or (by default) F# types. I might leave your cast function the way it is, and make a tryCast that uses options.

let tryCast<'a> o =
    match box o with
    | :? 'a as output -> Some output
    | _ -> None

Then you could use it like this:

ci |> tryCast<ITalk> |> Option.iter (fun it -> it.Talk())

In this case, Option.iter takes the place of your null test.

like image 104
Joel Mueller Avatar answered Dec 25 '25 20:12

Joel Mueller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!