首页 > 解决方案 > F# - 使用带有 out 参数的 C# 方法(在数组内和 void 返回)

问题描述

我已经阅读了 cs-out 的-f-equivalent-of-cs-out但我仍然无法使其适用于我的情况(最简单的解决方案/语法)。

我在 C# 项目中有这个方法:

//<Project Sdk="Microsoft.NET.Sdk">
//<TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks>

public static void ABC(out byte[] a, out byte[] b, byte[] c)
{
    var aaa = new byte[10];
    var bbb = new byte[10];            
    a = aaa;
    b = bbb;
}

现在,我想在 F# 项目中使用它:我正在使用FSharp.Core 4.7.2

(* <Project Sdk="Microsoft.NET.Sdk">
   <TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks> *)

let a,b = ABC(c)

我正在模仿的语法,TryParse并且编译时没有错误:

let success, number = System.Int32.TryParse("0")

我调用的编译器ABC(c)抱怨签名要求 3 个参数,而不是 1 个这一事实。
TryParse我看到 2 个差异相比:

编译器接受以下语法:

let a = Array.empty<byte>
let b = Array.empty<byte>
ABC(ref a, ref b, c) 

但:

  1. 我认为在ref这里使用是不正确的,而不是这样使用(因为a并且b不可变)
  2. 我想使用类似于的简洁语法,TryParse并且我想知道为什么它在这里不起作用

我可以更改 C# 项目代码,但替换该项目中的所有out参数将是第二步,如果我有困难或疑问,可能是一个新问题。

[更新:参数位置]

我玩了一点,似乎我发现“简单”语法(不传递 ref 参数)被破坏了。

public static void TryParseArray(string input, out int[] result) {
    result = new int[0];
}

public static void TryParseArray_2(out int[] result, string input) {
    result = new int[0];
}
let arr = csharp.TryParseArray("a")            // OK
let arr = csharp.TryParseArray_2("a")          // ERROR

似乎 out 参数必须在 C# 方法的末尾(= 后面不跟普通参数),以使 F# 可以将它们用作返回的元组。

标签: f#outc#-to-f#

解决方案


您正确地注意到,将参数转换为返回元组的“简化”F# 语法仅适用于非常有限的情况 - 仅当您有一个参数并且它是最后一个参数时。换句话说,这个特性有助于一些常见的模式,但它并不能完全取代 out 参数。

如果要out在 F# 中使用参数,可以使用&var语法传递对局部可变变量的引用,也可以指定类型的引用单元格int ref作为参数。下面显示了使用标准TryParse方法的两个选项:

// Using a local mutable variable
let mutable n = 0
Int32.TryParse("42", &n)
printfn "Got: %d" n

// Using a reference cell initialized to 0 
let n = ref 0
Int32.TryParse("42", n)
printfn "Got: %d" n.Value

推荐阅读