从F#中查看C# Windows表单项目代码

3
我有一个打开的C# Windows表单项目,其中包含一些C#代码。

问题:我如何拥有一个F#文件,可以在其中编写F#代码,但仍然引用Form1.cs中的所有C#代码(包括GUI)?

我可以成功地做到这一点:
- 创建一个C# Windows Forms项目
- 创建一个F#库项目
- 从我的C#项目引用F#库DLL
- 这样我就可以从C#调用F#函数。
但是我仍然看不到来自F#的按钮和文本框。
我明白这是因为它是一个库,无法引用System.Windows.Forms。

那么我该怎么办呢?我不想让它成为一个库或其他东西,我只想让它成为一个文件,使我能够编写F#代码并引用我的C#表单和代码。

我想你可以说我想要一个F#文件,它也是一个"partial class Form1",这样我就可以继续使用F#编写同一个项目的代码。 我该怎么做?

你是否已经将F#中的Form1、Button或函数声明为public? - Anonymous
2个回答

8
如果我理解正确,您实际上是在询问如何构建应用程序,以便您可以使用WinForms设计器(仅在C#/ VB中可用)创建窗体,并同时在F#中编写应用程序逻辑。
首先,没有办法在单个项目中混合两种语言,这意味着您不能像在F#和C#中有一部分的“partial”类一样编写代码(从技术上讲几乎不可能)。因此,唯一的选择是编写一个F#项目和一个C#项目,并相互引用。有两种方法可以做到这一点:
(基于您的答案和评论,我认为您可能更喜欢第一种方法)
从F#应用程序引用C#库:一种选择是创建一个简单的WinForms库项目,在其中包含使用WinForms设计器创建的窗体(以及可能的其他控件等),而不包含其他内容。然后,您将从F#中创建的应用程序中引用此库,并在F#应用程序中实现所有用户交互。
如果您确保将WinForms设计器创建的YourForm类以及添加到表单中的所有相关控件标记为public,则可以从F#应用程序引用该表单并对其进行控制。
  • 我在我的书中的一个示例中使用了这种方法,因此如果您正在寻找示例,则可以查看第14章(查找“FSharpEffects”的源代码)。

从C#应用程序引用F#库:当您以这种方式构建应用程序时,您需要创建一个F#库,公开应用程序所需的所有基本功能,然后从C#应用程序引用它。 C#应用程序将添加所有用户界面交互代码,并调用F#库执行实际工作。

在这种情况下,F#库不知道C#表单的任何信息。如果您从F#库中引用System.Windows.Forms,则可能会将一些WinForms控件作为参数(例如,配置它们和加载数据),但它不会知道在C#中声明的控件。

一种可能的扩展方案是在F#库中声明一个接口,然后在C#应用程序中实现该接口,并将其实现传回给F#库。接口可以公开应用程序的一些重要属性(例如,提供对所有重要WinForms控件的访问)。一旦您向F#库提供了接口的实现,F#库就可以使用它来操作应用程序。
(使用接口的方法需要编写更多代码,可能不够灵活,但如果您想在C#中编写主要应用程序并在那里声明表单,则这可能是最佳选项)

首先,我昨天刚买了你的书,我非常喜欢它。 其次,感谢你和Manning在购买纸质版本后提供免费的PDF副本。 我还没有安装 .Net 4所以无法编译你的第14章。 与此同时,你的回复足够清晰详细地回答了我的问题。 遗憾的是,一个部分是C#,部分是F#的类几乎不可能。这就是公共语言基础设施应该给我们的好处。 既然C#和F#都编译成相同的中间语言,我希望这不仅是可能的,而且是必然的。 - PeterM
5
@悲观主义者,如果这样的话,我建议你更改你的用户名 ;) - Benjol
@Benjol:谢谢你让我笑了 :) 我是个悲观主义者,不是因为我期望最坏的结果(那是“街头”定义,杯子半空等等,不是真正的哲学),而是因为我认为现在存在的东西很糟糕。我想这与我们刚刚发现的关于C#和F#的事情是一致的。;) - PeterM
@Pessimist - 由于你不能在多个C#项目之间共享部分类,我不知道为什么假定你可以在C#和F#项目之间共享部分类。我同意当F#项目有更好的UI方案时会很好(Silverlight,我看着你),但让我们不要假设奇迹会发生。 - Joel Mueller

0

你需要在 F# 项目中添加对 System.Windows.Forms.dll 的引用,并将 Form1 类及其成员的可见性设置为 public

(库也可以引用 System.Windows.Forms;这就是可重用控件项目的作用)

你还需要一些方法来调用 F# 代码;你可能想把 F# 项目作为一个 EXE(调用 Application.Run),而将 C# 项目作为一个库。


你的 F# 代码需要一个 Form1 类的实例。你可能想要继承它。 - SLaks
我不想让F#代码成为可执行文件,然后C#成为库,因为整个项目已经是C#。我真的只想为现有的项目及其控件和功能编写F#代码,这些都是用C#编写的。 - PeterM
是的,但C#项目需要为F#代码提供一个实例。最简单的方法是将所有代码保留在C#中,但从F#调用它,提供一个继承的Form1实例。否则,你会有一个循环引用。 - SLaks
我不是面向对象的大师,但我不认为继承会有所帮助。我不能将我的F#代码实现为Form1的部分类吗?谷歌说F#不支持部分类,但我不知道这是否过时。 - PeterM
这是完全不可能的(部分类在编译时合并)。你需要学习基本的面向对象概念。 - SLaks
显示剩余4条评论

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