首页 > 解决方案 > 使用 UWP、.NET Core v2.0.3 和 C# v7.3 从 C# 方法调用 F# 可区分联合?

问题描述

我们应用的 UWP 库限制我们使用 .NET Core 2.0.3。我们的代码使用 C# v7.3,我们一直在试验 F#。

在我们的 .NET Core v2.0.3 和 C# v7.3 版本中,如何处理从 F# 返回的有区别的联合?

一些建议是使用 C# 开关来处理 F# 函数返回的有区别的 union

将以下 F# 和 C# 代码放入带有 F# 和 C# 项目的测试控制台应用程序中...

F#

type LogLevels =
| Error
| Warning
| Info

C# 调用 F#

private static void Main()
{
    LogLevels level = LogLevels.Info;
    switch (level.Tag)
    {
        case LogLevels.Tags.Error:
            Console.WriteLine("error");
            break;
        case LogLevels.Tags.Warning:
            Console.WriteLine("warning");
            break;
        case LogLevels.Tags.Info:
            Console.WriteLine("info"); //prints info
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

....正如@madreflection 所说,工作正常。

但是如果System.Threading.Tasks.Task返回 a 而不是 aint我得到编译器错误CS8370: Feature ‘type pattern’ is not available in C# 7.3. Please use language version 9.0 or greater.

在我的尝试中,我使用在 C# 中工作并且应该在 F# 中工作的 API 从 Azure 密钥库中检索密钥。

F# 代码是……</p>

type public SENSITIVE_ITEM =
| SECRET_C of KeyVaultSecret
| KEY_C of KeyVaultKey

type public TASK_SENSITIVE_ITEM =
| TASK_GET_SECRET_C of Task<Azure.Response<KeyVaultSecret>>
| TASK_GET_KEY_C of Task<Azure.Response<KeyVaultKey>>

let GetAsync ( item : SENSITIVE_ITEM) (vaultURI : Uri) : TASK_SENSITIVE_ITEM =
    match item with
    | SECRET_C(secret) -> VClient_Secret(vaultURI).GetSecretAsync(secret.Name) |> TASK_GET_SECRET_C
    | KEY_C(key) -> VClient_Key(vaultURI).GetKeyAsync(key.Name) |> TASK_GET_KEY_C

...而我的单元测试中的C# 代码GetAsync是 ...</p>

public void GetAsync_Key()
{
    KeyVaultKey key = new KeyVaultKey(keyName);

    var fs_sensitive_item_key = KeyVaultAccess.SENSITIVE_ITEM.NewKEY_C(key);

    var task = KeyVaultAccess.GetAsync(fs_sensitive_item_key, vaultUri);
    switch (task)
    {
        case KeyVaultAccess.TASK_SENSITIVE_ITEM.TASK_GET_KEY_C:
            Console.WriteLine("got a key task.");
            break;
        case KeyVaultAccess.TASK_SENSITIVE_ITEM.TASK_GET_SECRET_C:
            Console.WriteLine("got a secret task.");
            break;
        default:
            break;
    }

    Assert.True(false);
}

两个 C#case匹配表达式给出了错误。这可能是因为 C# 7.0.3 不支持开关中的模式匹配。(如错误所说)。

这是一个问题,因为.NET 5.0 不支持 UWP,而使用 C# v9.0 或更高版本则需要此功能。

那么,在我们有限的 .NET Core v2.0.3 和 C# v7.3 版本中,如何处理从 F# 返回的有区别的联合?

标签: c#uwpf#

解决方案


F# 编译器为有区别的联合生成所谓的“增强”。

从 C#使用您的类型时,您可以使用生成的属性LogLevel访问/检查特定情况。Is[caseName]

https://sharplab.io/#v2:DYLgZgzgNAJiDUAfALgTwA4FMAEAZA9gOa6YBumwE2AvALABQi2AogE6v6sNMDqAhqwB2AS0GFu2AJKCw+IA

具有案例值的可区分联合。

https://sharplab.io/#v2:DYLgZgzgNAJiDUAfA9gBwKYDsAEBlAnhAC7oC2AdACoAWATugIYwCWmA5lQxANYQCwAKEFF8GbAHVaDVBlrYAvNkGJsAQWzIw2Sl24AeAEbJkwAHzLsAIQ1adPPcVqs2poA=


推荐阅读