Mono是.NET的子集吗?

8

我知道反过来并不一定成立,但如果我的应用程序在Mono上运行良好,那么如果我切换到真正的.NET框架,它是否保证可以正常工作?如果不能,我在哪里可以找到注意事项列表?

4个回答

18

Mono和.NET都是ECMA/ISO CLI规范族的超集。但是,.NET和Mono都不是对方的子集。Mono和.NET在ECMA/ISO CLI之上添加了一些功能,但是虽然Mono实现了许多.NET的增强功能,但.NET没有实现Mono的任何增强功能。

以下是一些示例:

  • Mono具有更大的数组。这实际上不是ECMA/ISO CLI规范的增强功能,而是可选功能:规范指出数组索引必须是32位或64位。.NET选择了32位,但Mono选择了64位,因为具有10亿个及以上条目的数组在超级计算应用程序中非常普遍,而Mono在该市场上占有相当强势地位。因此,如果您的应用程序具有数十亿个条目的数组,在Mono上运行得很好,但在.NET上则无法工作。
  • Mono在VM中内置了continuations。这对于游戏编程非常重要。
  • Mono具有本地SIMD支持,用于数组上的并行操作,这些操作被映射到本地CPU SIMD指令(MMX、SSE、VMX)。
  • Mono具有编译器即服务,而Microsoft只是模糊地谈论某个未指定版本的.NET。
  • Mono有很多额外的库,特别是绑定到除Windows Forms之外的图形库(wx.NET、Gtk#、Cocoa#等)

但请注意,除了数组之外,所有这些都可以通过它们的命名空间清晰地区分,因为它们都不属于SystemMicrosoft命名空间。


编辑:实际上,上述大部分扩展都是明确设计用于在.NET上工作的。例如,Mono.Simd 也可以在.NET上运行,但由于缺少Mono VM的运行时支持,它的速度非常慢。(基本上,所有SIMD操作都是用C#实现的,但Mono编译器检测到这些调用并将它们替换为相应的汇编指令。这样,它们可以在.NET上工作,但没有特殊处理,它们会明显变慢。)此外,C# REPL目前正在重新实现,以便在未来可以在.NET上工作,它是基于Reflection.Emit 实现的(目前它直接调用Mono编译器)。Gtk# 在Windows和.NET上运行良好。

只有 Mono.Tasklet 库不能在.NET上实现,因为它需要VM级别的支持连续性。


Mono.SIMD在.NET运行时上确实可以工作,但是它会退回到软件模式。 - Matthew Olenik
@Matt Olenik:谢谢。显然,我混淆了SIMD和continuations。SIMD可以工作,但速度较慢,而Mono.Tasklet则不行。 - Jörg W Mittag

3

不过,如果你只使用微软定义的类,那么就没有问题了。Mono包括几个可替代的UI框架(Gtk#、wxWindows for .NET等)。


2
Mono是CLI标准的实现,CLR也是如此。
它包括许多在.NET BCL中找到的库,但不包括任何特定于Windows的库(WMI是一个例子)。
只要您遵循不特定于Windows的功能,您应该就没问题了。
Mono团队创建了一个工具来检查您的代码是否可以在Mono上运行- MoMA,即Mono迁移分析器。
至于将Mono代码与Microsoft编译器一起使用,只要您包含正在使用的库并且在Linux上没有进行任何pInvokes,您应该就没问题了。

我在谈论相反的情况。 - Aillyn

2
Mono并未扩展BCL API,至少不是在System命名空间中。因此,如果一个应用程序仅使用System命名空间中的类型,那么可以十分确定它将是可移植的,无需从Mono重新编译到.NET。当然,在.NET世界中,你将无法找到任何Mono命名空间中的内容。从Mono FAQ中可以得知这一点。
您是否计划拥抱和扩展.NET?
拥抱一项良好的技术是好的。以不兼容的方式扩展技术对用户来说是不好的,因此我们不打算对这些技术进行不兼容性的更改。
如果您有创新的想法,并且想要创建新的类,我们鼓励您使这些类在Mono和.NET中都能够正常运行。Mono目前附带了许多额外的库,这些库要么是由Mono社区的成员或其他团体开发的。在某些情况下,我们发现Microsoft的某些部分不完整,但是我们避免破坏API,而是在新程序集中公开缺失的功能(请参见Mono.Security)。

+1,这是我在回答中忘记提到的重要观点:Mono团队所做的几乎所有“专有”扩展都是以库形式存在的,因此它们也可以在.NET上工作。例如,连续性在Mono中具有VM支持,但它们也可以在.NET上工作。它们速度太慢,实际上无法使用,但它们确实可以工作(至少对于相当慷慨的“工作”定义而言)。使用Mono编译器直接实现的C# REPL正在通过Reflection.Emit重新实现。唯一无法在.NET上支持的是Mono.Simd。 - Jörg W Mittag
我混淆了SIMD和continuations。实际上,情况恰恰相反:SIMD在.NET上工作,通过在C#中模拟CPU级别的SIMD指令来实现。而continuations则不行,因为它们需要VM级别的continuation支持。 - Jörg W Mittag

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