当前位置:  开发笔记 > 编程语言 > 正文

F# - 关于传递给C#方法的参数 - 它们是元组还是什么?

如何解决《F#-关于传递给C#方法的参数-它们是元组还是什么?》经验,为你挑选了1个好方法。

我读了很多次

从F#或任何其他.NET语言生成的程序集(几乎)难以区分.

然后我在.NET 4(beta 2)上试验F#和C#interop.我用以下类创建了一个新的解决方案和一个C#项目:

public class MyClass {
    public static int Add(int a, int b) { return a + b; }
}

然后,在F#项目上,在引用C#项目之后,我尝试了:

MyClsas.Add(4, 5) |> printfn "%d" // prints 9 (no kidding!)

到现在为止还挺好.然后又出现了我多次读过的另一句话(也许在不同的书上):

将参数传递给其他.NET库中的函数时,使用类似".MethodName(parm1,parm2)"的语法,即参数作为元组传递.

将其添加到我曾经在SO上阅读的内容(但是无法找到它链接到的),在OP试图创建使用的问题[ 4, 5, 6 ](当他的意思[4; 5; 6])时:

"逗号是'元组创建运算符',因为其他一切都使用了分号."

然后我将我的课修改为以下内容:

public class MyClass {
    public static int Add(int a, int b) { return a + b; }
    public static int Add(Tuple a) { return a.Item1; }
}

现在我尝试在F#上使用它:

MyClass.Add(4, 5) |> printf "%d" // prints ... (keep reading!)

因此,加上上面的三个引文,可以得出结论:

F#会在看到时创建一个元组 (4, 5)

然后它将调用过载 Add(Tuple)

所以它将打印4

令我惊讶的是,它打印了9.不是很有趣吗?

这里到底发生了什么?上述引文和这些实际观察似乎是矛盾的.你可以证明F#的"推理",并且如果可能的话可能指向一些MSDN文档吗?

谢谢!

编辑

(添加更多信息(来自Blindy的回答))

如果你这样做:

MyClass.Add((4, 5)) |> printfn "%d" // prints 9

F#调用Add(Tuple)过载.

但是,如果您使用以下方法创建另一个F#项目(因此使用不同的程序集):

namespace MyFSharpNamespace
type MyFShapClass = class
    static member Add x y = x + y
    end

您可以像这样在C#上使用它

public static void Main(string[] args) {
    MyFSharpNamespace.MyFSharpClass.Add(4, 5);
}

到现在为止还挺好.现在,当您尝试从F#(来自另一个项目,另一个程序集)使用它时,您必须:

MyFSharpNamespace.MyFSharpClass.Add 4 5 |> printfn "%d"

如果你传递参数,因为(4, 5)F#不会编译,因为Addint -> int -> int,而不是(int * int) -> int.

怎么了?!?



1> Pavel Minaev..:

将参数传递给其他.NET库中的函数时,使用类似".MethodName(parm1,parm2)"的语法,即参数作为元组传递.

它比那更可怕.从语言规范中查看方法重载分辨率strait的描述.

基本上,它所说的是方法调用中的参数实际上并不是一个元组.它是一个语法元组,意思是逗号分隔的某些东西,但括号是方法调用语法的一部分,逗号也是如此.例如,这就是为什么o.M(a=1, b=2)不是使用两个布尔元组的方法调用,而是两个命名参数.

因此,通常,每个逗号分隔的组件只映射到一个不同的参数.因此,为什么Add(1, 2)调用Add(int, int)超载和Add((1, 2))调用Add(Tuple).这里没有歧义.

但是,针对您的特定情况启动的特殊情况是:

如果没有命名的实际参数,并且只有一个候选方法M,只接受一个非可选参数,则arg忽略to to tuple form 的分解,并且有一个名为actual argarg本身.

因此,当您删除除元组之外的所有重载时,括号内的所有内容突然被有效地视为调用中的元组构造函数.但是,如果你愿意例如有两个重载,Add(int)并且Add(Tuple),然后形式的呼叫Add(1,2)并不能解决所有.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有