C# WPF 项目无法调用 F# 库。

4

最近我从我的项目中暂停了2周的时间来编写一个体量不小的文件解析器和数值误差检查器。出于兴趣,我决定用F#语言编写它们。这是一个很棒的决定。

以前用VB编写的程序超过1000行,在F#中只需170行就能搞定。太棒了。

现在我回到了我的项目中,想要使用一个F#库来完成一些解析工作并可能读写一个XML保存文件。但是我无论如何都无法弄清楚如何从C# WPF应用程序中调用一个F#库。

我正在使用Microsoft Visual 2010 Professional,并尝试参考这篇文章: http://www.devjoy.com/2013/02/c-to-f-interop-sharing-a-domain-model/ 还有一些stackoverflow的帖子:

  1. Create a WPF project.
  2. Added an F# library project to the solution.
  3. Added a reference to the F# library to C# project via: Right click project file in SolutionExplorer, click 'Add Reference', selected 'MyFSharpLib' from projects tab and click Add.
  4. I then added some test code to the default F# file module1.fs:

    module Module1
    
    let Add a b = a + b
    
  5. And tried to call it from C#:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication2
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
    public MainWindow()
    {
        InitializeComponent();
    }
    
    // Call F# library
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        int a = Module1.Add(1, 2);
    }
    }
    }
    

这会导致出现错误,提示:“当前上下文中不存在名为'Module1'的名称。”

我认为问题出在程序集上。我注意到一些代码示例使用了using Microsoft.FSharp.Core。这是否是问题所在?我尝试添加它,但在.NET标签下找不到它。

这让我很疯狂,请给予帮助,万分感谢。


1
你有构建这个库吗? - gasroot
这是一年中最糟糕的时刻。谢谢伙计。 - Steel Nation
欢迎加入白痴俱乐部,这是你的会员卡。我会稍后收取你的会费 - 我是主席。 - SQLMason
@SteelNation 不用担心 - 如果我没记错的话,C#编译器仍然会为引用它的解决方案中的其他项目提供智能感知,而无需实际构建C#项目。F#编译器(实际上是VS语言服务)只有在项目实际编译没有错误时才会更新其提供给引用项目的智能感知。 - Jack P.
@JackP。啊,所以IntelliSense在编译之前不知道那里的库。当IntelliSense没有立即弹出时,你知道你已经经常开发.NET了,这让你担心。 - Steel Nation
显示剩余3条评论
1个回答

5

看起来你已经找到了答案——构建F#项目——但我将为一个几乎具有相同症状但根本原因不同的问题提供答案(供后人参考)。

如果你使用提供的示例F#代码,即一个简单名称的模块(没有命名空间),那么需要知道的是,当从C#访问F#模块时,你需要使用global关键字。例如,这是你从C#调用你定义的Add函数的方法:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = global::MyModule.Add(1, 2);
        }
    }
}

除非你有特别的理由不这样做,通常最好使用命名空间来定义你的模块,例如:module MyNamespace.Module1


真的吗?对我来说似乎很正常。是当你有多个模块时才会出现问题吗? - Steel Nation
@SteelNation 不,我创建了一个包含两个项目的示例解决方案——一个包含您提供的确切 F# 代码,另一个包含我的答案中的 C# 代码(尽管我删除了 using 声明)。在添加了 global 关键字之前,我无法调用 MyModule.Add。这可能是 VS2010 和 VS2012(即 F# 2.0 和 3.0)之间发生的变化。 - Jack P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接