I have a stupid problem, I need to implement in F# class the interface which have following method:
public interface IMyInterface
{
T MyMethod<T>() where T : class;
}
And I am struggling myself doing it in F#. I have tried different ways. But the problem is that an object of type T must be returned. Null is not accepted:
type public Implementation() =
interface IMyInterface with
member this.MyMethod<'T when 'T : not struct>() = null
Error: The member 'MyMethod<'T when 'T : not struct> : unit -> a' when a': not struct and 'a: null does not have the correct type to override the corresponding abstract method. The required signature is 'MyMethod<'T when 'T : not struct> : unit -> 'T when 'T: not struct'
So I have tried to put T as argument to the class, but still no I finished with error:
type public Implementation(data : 'T when 'T : not struct) =
interface IMyInterface with
member this.MyMethod<'T when 'T : not struct>() = data
Error: The member 'MyMethod<'T when 'T : not struct> : unit -> 'T when 'T : not struct' does not have the correct type to override the corresponding abstract method.
Thank you for help.
Instead of returning null (which is inferred to have some type 'a, check by returning null :?> 'T) you can use
type public Implementation() =
interface IMyInterface with
member __.MyMethod<'T when 'T : not struct>() = Unchecked.defaultof<'T>
I prefer __ over this when it's not used.
TL;DR;
The class constraint in C# implicitly includes null. Unfortunately specifying that in F# is not allowed:
member __.MyMethod<'T when 'T : not struct and 'T : null>() = Unchecked.defaultof<'T>
results in:
The member 'MyMethod<'T when 'T : not struct and 'T : null> : unit -> 'T when 'T : not struct and 'T : null' does not have the correct type to override the corresponding abstract method. The required signature is 'MyMethod<'T when 'T : not struct> : unit -> 'T when 'T : not struct'.
But then, using classes and interfaces like these cross-language requires special attention anyways, because C# and the CLR allow null values whereas F# doesn't.
For comparison against null best overload F# isNull (see this answer):
let inline isNull (x:^T when ^T : not struct) = obj.ReferenceEquals (x, null)
unless your type allows null when you can use standard isNull:
[<AllowNullLiteral>]
type Foo() =
member __.Bar() = ()
(Implementation() :> IMyInterface).MyMethod<Foo>() |> isNull // true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With