[英]Calling F# discriminated union from C# method using UWP, .NET Core v2.0.3 and C# v7.3?
Our app's UWP libraries limit us to using .NET Core 2.0.3.我们应用程序的 UWP 库限制我们使用 .NET Core 2.0.3。 Our code uses C# v7.3 and we have been experimenting with F#.
我们的代码使用 C# v7.3,我们一直在试验 F#。
How does one handle a discriminated union returned from F# in in our versions of .NET Core v2.0.3 and C# v7.3?在我们的 .NET Core v2.0.3 和 C# v7.3 版本中,如何处理从 F# 返回的有区别的联合?
Some advice is to use a C# switch to handle an F# function returned discriminated union .一些建议是使用 C# 开关来处理 F# function 返回的歧视联合。
Putting the following F# and C# code in a test Console app with and F# and C# project...将以下 F# 和 C# 代码放入测试控制台应用程序中
F# F#
type LogLevels =
| Error
| Warning
| Info
C# calling F# 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();
}
}
….works fine just as @madreflection says. ....正如@madreflection 所说,工作正常。
But if a System.Threading.Tasks.Task
is returned instead of an int
I get the compiler error CS8370: Feature 'type pattern' is not available in C# 7.3. Please use language version 9.0 or greater.
但是,如果返回
System.Threading.Tasks.Task
而不是int
,我会收到编译器错误CS8370: Feature 'type pattern' is not available in C# 7.3. Please use language version 9.0 or greater.
CS8370: Feature 'type pattern' is not available in C# 7.3. Please use language version 9.0 or greater.
In my attempt I retrieve a key from an Azure key vault using an API that works in C# and should in F#.在我的尝试中,我使用在 C# 中工作的 API 从 Azure 密钥保险库中检索密钥,并且应该在 Z6209B1604BFEF853 中。
The F# code is … F# 代码是……
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
...and the C# code in my unit test for GetAsync
is … ...而我的 GetAsync 单元测试中的
GetAsync
代码是...
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);
}
The two C# case
match expressions give the error.两个 C#
case
匹配表达式给出了错误。 This is probably because C# 7.0.3 doesn't support pattern matches in switches.这可能是因为 C# 7.0.3 不支持开关中的模式匹配。 (as the error says).
(如错误所说)。
This is a problem as UWP is not supported in .NET 5.0 which is needed to use C# v9.0 or greater.这是一个问题,因为UWP 在 .NET 5.0 中不受支持,这是使用 C# v9.0 或更高版本所必需的。
So, How does one handle a discriminated union returned from F# in in our limited versions of .NET Core v2.0.3 and C# v7.3?那么,在我们的 .NET Core v2.0.3 和 C# v7.3 的有限版本中,如何处理从 F# 返回的有区别的联合?
The F# compiler generates so called "augmentations" for Discriminated Unions. F# 编译器为可区分联合生成所谓的“增强”。
When using your LogLevel
type from C# you can access/check for a certain case using the generated Is[caseName]
Properties.当使用 C# 中的
LogLevel
类型时,您可以使用生成的Is[caseName]
属性访问/检查特定案例。
https://sharplab.io/#v2:DYLgZgzgNAJiDUAfALgTwA4FMAEAZA9gOa6YBumwE2AvALABQi2AogE6v6sNMDqAhqwB2AS0GFu2AJKCw+IA https://sharplab.io/#v2:DYLgZgzgNAJiDUAfALgTwA4FMAEAZA9gOa6YBumwE2AvALABQi2AogE6v6sNMDqAhqwB2AS0GFu2AJKCw+IA
Discriminated Union with case values.具有案例值的可区分联合。
https://sharplab.io/#v2:DYLgZgzgNAJiDUAfA9gBwKYDsAEBlAnhAC7oC2AdACoAWATugIYwCWmA5lQxANYQCwAKEFF8GbAHVaDVBlrYAvNkGJsAQWzIw2Sl24AeAEbJkwAHzLsAIQ1adPPcVqs2poA= https://sharplab.io/#v2:DYLgZgzgNAJiDUAfA9gBwKYDsAEBlAnhAC7oC2AdACoAWATugIYwCWmA5lQxANYQCwAKEFF8GbAHVaDVBlrYAvNkGJsAQWzIw2Sl24AeAEcqqqHzAVApoLs=kAeAEb
With the advice from madreflection I figured this out...在madreflection的建议下,我想通了……
Use the *.Tags.*
nested class members as follows...使用
*.Tags.*
嵌套 class 成员如下...
switch (task.Tag)
{
case KeyVaultAccess.TASK_SENSITIVE_ITEM.Tags.TASK_GET_KEY_C:
Console.WriteLine("got a key task.");
break;
case KeyVaultAccess.TASK_SENSITIVE_ITEM.Tags.TASK_GET_SECRET_C:
Console.WriteLine("got a secret task.");
break;
default:
Console.WriteLine("default.");
break;
}
This works.这行得通。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.