简体   繁体   中英

Invoking an F# library from C#

I have an F# class library that is consumed by C#.

The F# library has 2 two types and one simple function that I want to invoke from my C# code.

namespace HFNZ.InfectionStatus.ClassLibrary

type Result = 
    | Positive
    | Negative

type TestType = 
    | AntiHBc of Option<Result>
    | AntiHBs of Option<Result>
    | HBeAg of Option<Result>
    | HBsAg of Option<Result>
    | HBVDNA of Option<Result>

module Program =

    let getHVBStatus (test1, test2, test3, test4, test5) =
        match test1 test2 test3 test4 test5 with
        | AntiHBc   (Some(Positive)), 
          AntiHBs   (Some(Positive)), 
          HBeAg     (Some(Positive)), 
          HBsAg     (Some(Positive)), 
          HBVDNA    (Some(Positive))  -> "Normal"

        | _ -> "Elevated"

This is my C# code:

var positive = new FSharpOption<Result>(Result.Positive);
var antiHBc =  TestType.NewAntiHBc(positive);
var AntiHBs = TestType.NewAntiHBs(positive);
var HBeAg = TestType.NewHBeAg(positive);
var HBsAg = TestType.NewHBsAg(positive);
var HBVDNA = TestType.NewHBVDNA(positive);

Program.getHVBStatus(antiHBc, AntiHBs, HBeAg, HBsAg, HBVDNA);

The C# code does not compile due to this error:

Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 1: cannot convert from 'InfectionStatus.ClassLibrary.TestType' to 'Microsoft.FSharp.Core.FSharpFunc<InfectionStatus.ClassLibrary.TestType, Microsoft.FSharp.Core.FSharpFunc<InfectionStatus.ClassLibrary.TestType, Microsoft.FSharp.Core.FSharpFunc<InfectionStatus.ClassLibrary.TestType, Microsoft.FSharp.Core.FSharpFunc<InfectionStatus.ClassLibrary.TestType, System.Tuple<InfectionStatus.ClassLibrary.TestType, InfectionStatus.ClassLibrary.TestType, InfectionStatus.ClassLibrary.TestType, InfectionStatus.ClassLibrary.TestType, InfectionStatus.ClassLibrary.TestType>>>>>'    UnitTestProject1    D:\F#\Code\InfectionStatus.ClassLibrary\UnitTestProject1\UnitTest1.cs   21  Active

I tried changing the F# function to use tuples instead of currying but still getting a compilation error.

What is the correct way to pass multiple arguments (non-primitive types) from C# to F#?

In your F# function getHVBStatus , you are missing commas between the parameters that you want to pattern match agains (on the match line). As a result, the F# type inference turns test1 into a function that takes test2 and all the other parameters as arguments.

This is quite hard to spot just from the C# compiler error message, but if you hover over test1 to see the inferred type in F#, you'll immediately see that there's something wrong. Adding commas on the match line should fix the problem:

let getHVBStatus (test1, test2, test3, test4, test5) =
    match test1, test2, test3, test4, test5 with
    | AntiHBc   (Some(Positive)), 
      AntiHBs   (Some(Positive)), 
      HBeAg     (Some(Positive)), 
      HBsAg     (Some(Positive)), 
      HBVDNA    (Some(Positive))  -> "Normal"
    | _ -> "Elevated"

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