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