简体   繁体   中英

F# class not implementing interface function

I'm newbie to F# and experimenting it. I'm trying to implement a F# interface.

This is my F# file:

namespace Services.Auth.Domain

type IAuthMathematics = 
    abstract Sum : unit -> int

type AuthMathematics(a : int, b : int) = 
    member this.A = a
    member this.B = b
    interface IAuthMathematics with
        member this.Sum() = this.A + this.B

When using it in C# and pressing F12, giving me this

[CompilationMapping(SourceConstructFlags.ObjectType)]
public class AuthMathematics : IAuthMathematics
{
    public AuthMathematics(int a, int b);

    public int A { get; }
    public int B { get; }
}

[CompilationMapping(SourceConstructFlags.ObjectType)]
public interface IAuthMathematics
{
    int Sum();
}

Where are my sum function and properties initialization ?

When you hit F12 from C# (I'm assuming that's Visual Studio, right?), it doesn't show you the source code (obviously - because the source is in F#), but rather it uses metadata to reconstruct what the code would look like if it was written in C#. And while it's doing that, it shows only public and protected things, because those are the only ones you can use anyway.

At the same time, interface implementations in F# are always compiled as "explicit" , aka "private", so that's why they wouldn't show up in metadata-reconstructed view.

And of course, property initializers are part of the constructor's body, so naturally they're not shown either.

For reference, your F# implementation would look something like this in C#:

public class AuthMathematics : IAuthMathematics
{
    public AuthMathematics(int a, int b) {
        A = a;
        B = b;
    }

    public int A { get; private set; }
    public int B { get; private set; }

    int IAuthMathematics.Sum() { return A + B; }
}

You can create an F# class that looks like a C# class with implicit interface member implementation. Because there is no implicit implementation in F#, you must both define the public member and implement the interface explicitly. The result:

namespace Services.Auth.Domain

type IAuthMathematics = 
    abstract Sum : unit -> int

type AuthMathematics(a : int, b : int) = 
    member this.A = a
    member this.B = b

    member this.Sum() = this.A + this.B

    interface IAuthMathematics with
        member this.Sum() = this.Sum()

This is useful because it allows you to use the Sum() method directly with an AuthMathematics reference without having to cast to IAuthMathematics .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM