C# to F# Interop: How to specify a C# method's optional parameter in F# function type signature?

StackOverflow https://stackoverflow.com/questions/22397878

  •  14-06-2023
  •  | 
  •  

Question

I have the following method in some C# code:

Qux MyFunc(Foo foo, Bar bar, int baz = 1);

I want to add it as a field on my new F# Record type. I will assign the C# function later, to my record field, in F# code.

If I ignore the default nature of the final parameter baz, then my type would look like this:

type MyType = {
    MyFunc: Foo * Bar * int -> Qux
}

However, because we have the optional C# parameter, I wish to reflect that. I have tried using the Optional Attribute mentioned here, but it doesn't work:

type MyType = {
    MyFunc: Foo * Bar * [<Optional;DefaultParameterValue(null)>] int -> Qux
}

I have also tried other combinations such as the question mark prefix e.g. ?baz.

What is the correct way to do this (if it is at all possible)?

Update & summary

Whilst it is possible to do this on a type member, it is not possible to do this on a value (Record). I'm using F# 3.1, so this might be possible in future.

To be fair in rewarding points, I will upvote @Daniel-Fabian who confirmed this is the case, and mark @Mark-Seemann's workaround as the answer, because although it wasn't quite the answer that I was looking for, it solved my problem.

Was it helpful?

Solution 3

I'm not going to claim that I have a very elegant solution, but the following works.

Assume that the MyFunc method is declared on Class1.

You can declare the MyType record like this:

type MyType = {
    MyFunc: Foo * Bar * option<int> -> Qux
}

This doesn't enable you to directly assign the original MyFunc method to the record, but a little helper function does:

let myFunc (h : Class1) (foo, bar, baz : int option) =
    match baz with
    | Some(i) -> h.MyFunc(foo, bar, i)
    | _ -> h.MyFunc(foo, bar)

Now you can create a value of MyType like this:

let mt = { MyFunc = myFunc c1 }

assuming that c1 is an instance of Class1.

You can now use it to get various values of Qux:

let q2 = mt.MyFunc(Foo(), Bar(), None)
let q3 = mt.MyFunc(Foo(), Bar(), Some(42))

OTHER TIPS

You write your signature with a ? for optional parameters.

member this.MyFunc (foo, bar, ?baz) = Qux

or for just the signature

abstract member MyFunc : Foo * Bar * [<OptionalArgument>] baz : int option -> Qux

as is also written in http://msdn.microsoft.com/en-us/library/dd233213.aspx. However, it won't work in your case, because optional parameters are only allowed to type members and not values.

The signature observed from visual studio might help:

observe

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top