【发布时间】:2011-01-02 19:23:37
【问题描述】:
我已经读过很多次了
从 F# 或任何其他 .NET 语言生成的程序集(几乎)无法区分。
然后我在 .NET 4(beta 2)上试验 F# 和 C# 互操作。我使用以下类创建了一个新的解决方案和一个 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 ] 的使用的问题(当他的意思是 @ 987654324@):
“逗号是'元组创建运算符',其他一切使用分号。”
然后我将我的课程修改为以下内容:
public class MyClass {
public static int Add(int a, int b) { return a + b; }
public static int Add(Tuple<int, int> a) { return a.Item1; }
}
现在我尝试在 F# 上使用它:
MyClass.Add(4, 5) |> printf "%d" // prints ... (keep reading!)
因此,将上面的三个引用相加,可以得出结论:
- F# 在看到
(4, 5)时会创建一个元组 - 然后它会调用重载
Add(Tuple<int, int>) - 所以它会打印 4
令我惊讶的是,它打印了 9。是不是很有趣?
这里到底发生了什么?上述引文和这种实际观察似乎是矛盾的。您能否证明 F# 的“推理”是合理的,如果可能的话,也许可以指向一些 MSDN 文档?
谢谢!
编辑
(添加更多信息(来自 Blindy 的回答))
如果你这样做:
MyClass.Add((4, 5)) |> printfn "%d" // prints 9
F# 调用 Add(Tuple<int, int>) 重载。
但是,如果您使用以下命令创建另一个 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# 将无法编译,因为Add 是int -> int -> int,而不是(int * int) -> int。
发生了什么?!?
【问题讨论】:
标签: c# f# parameters tuples