在JVM上实现C#技术

98

有没有人正在尝试为JVM实现C#?作为一名Java开发者,我一直对C#虎视眈眈,但不愿放弃JVM的可移植性和成熟性,更不用说其多样化的工具库了。

我知道JVM和CLR之间存在一些重要的差异,但是有没有什么因素是无法解决的?


3
我也用Java编写了许多完全跨平台的应用程序 - 这对我和我的团队来说是家常便饭。 我们通常会在每个我们正式“认证”的平台上运行测试计划,但我认为多年以来,测试错误已经很少因为平台差异而出现了。 - Jared
1
为什么不直接使用Groovy呢?它几乎可以提供你在C#中喜欢的所有功能并且在Java中缺失的,而且它是运行在JVM上的。 - user283127
1
我在Windows上开发Java,另一个人在OSX上进行其部分工作,CI在Linux下运行所有测试,并且我们已经将软件部署到各种Windows和Linux服务器甚至Solaris上。因此,我想我可以说,我已经写了真正完全的跨平台Java程序有一段时间了。 - Esko
1
JavaVM 在 .NET 中实现;Java LIBS 的 .NET 实现;两个世界的互操作性 -> IKVM.NET (http://www.ikvm.net/) - gsscoder
1
我认为,如果你可以将.NET转换为JavaScript(例如JSIL),那么你应该能够将它转换为Java... - BrainSlugs83
显示剩余4条评论
9个回答

99
CLR和JVM之间存在非常显著的差异。
以下是一些例子:
- Java没有用户定义的值类型 - Java泛型与.NET泛型完全不同 - C#的许多方面都依赖于框架元素 - 委托等。即使是语言方面,您也需要将库移植过去。 - 在JVM级别上,Java不支持像属性和事件这样的东西。您可以模拟其中的一些内容,但并非完全相同。 - 我不认为Java有任何类似于按引用传递参数的等效物,即使在JVM级别上也是如此。 - 与不同内存模型相关的微妙之处可能会导致问题,尽管我不确定C#规范中有多少内容涉及此方面。 - 通常情况下,Java不支持不安全代码。 - JNI和P / Invoke之间的本地代码互操作性非常不同。这对您来说可能不是什么问题。 - 您必须模拟运算符重载和用户定义的转换。
您可能可以移植大量的C#代码,但在我看来,您将得到一个非常不令人满意的体验。
另一方面,您是否知道IKVM?它允许您在.NET中运行Java代码。

8
Java有finalizers,而.NET的终结行为也是不确定的。这两者之间可能存在一些微妙的差异,但我暂时想不出任何区别。我猜Java的可达性测试比.NET更强:只要另一个线程仍在运行实例方法,就不会进行终结。 - Jon Skeet
4
我认为你可以将值类型映射到引用类型。只需使每个赋值操作进行浅克隆即可! - Daniel Earwicker
4
@Earwicker: ...并改变数组分配,以及其他一些语义重要的地方?我怀疑如果可能的话,要让它工作起来将非常困难,而且结果也不是你想使用的东西。 - Jon Skeet
4
我认为泛型也是可以解决的。你需要生成一个Java类,其中包含额外的字段来保存类型参数的Class对象,这将增加一些开销,但是然后就可以使用new T()和typeof(T)了。 - Daniel Earwicker
31
这样做将让你两全其美:使用了有些过时的Java语言并运行在微软专有的平台上。 - Bart van Heukelom
显示剩余18条评论

44

访问http://code.google.com/p/stab-language

以下代码是JVM的Stab语言代码

using java.lang;
using stab.query;
public class Test {
   public static void main(String[] args) {
   // Sorts the arguments starting with "-" by length and then using the default   
        // string comparison
        var query = from s in Query.asIterable(args)
                    where s.startsWith("-")
                    orderby s.length(), s
                    select s;
        foreach (var s in query) {
            System.out.println(s);
        }
    }
}

7
Stab 将 C# 语言的核心功能移植到了 JVM 上,但是以非常兼容 Java 的方式来实现。虽然它并不完全兼容于针对 .NET CLR 的 C# 源代码,但是它允许 Java 程序员在使用类似 C# 的语言的同时,生成相同质量的字节码,并且可以与 Java 库和框架进行无阻力的互操作。这是将 C# 移植到 JVM 上的正确方法。 - RogerV
1
好的编程语言,运行在好的平台上...真希望我早些年就发现了它。 - Jefferey Cave

18

字节码转换器

Grasshopper 可以将CLR字节码转换为JVM字节码。主要用于Web应用程序,但不提供例如Windows Forms类的JVM实现。看起来有点过时了。网络上谈论的是ASP.NET 2.0、Visual Studio 2008等等。最初由@alex提到。

XMLVM 可以将CLR或JVM字节码作为输入,并产生相应的输出。此外,它还可以输出Javascript或Objective-C。目前仅有Subversion版本,没有正式发布版。"试验性开发版本,不适合在生产环境中使用。"

IKVM 的功能与OP所需的方向相反。它提供了一个在CLR上运行的JVM实现,一个JVM到CLR字节码的转换器和一个为Java生成CLR库方法存根的CLR库。http://www.ikvm.net/uses.html 由@Jon Skeet提到。

远程过程调用(RPC)

为什么不让CLR和JVM并行运行,并尽可能使通信无摩擦?这不是OP想要的,但其他一些答案已经以不同的方式离题了,所以让我们来谈论一下。

RabbitMQ,有一个免费选项,它是用Erlang编写的RPC服务器,具有C#,Java等API库。

jnBridge,许可证对于一些潜在用户来说可能太昂贵了。

gRPC和类似的现代RPC库提供广泛的语言支持,在这些语言中生成客户端库的代码生成器,数据的独立于语言的传输格式,高级功能如级联调用取消等。

编程语言

一次编写,到处运行 ;)

Haxe编译成C#/CLR、Java/JVM、Javascript、Flash、Python等,为每种目标语言提供互操作机制。在某种程度上可以看作是ActionScript3的继承者。似乎非常可靠,至少有一家公司实际上依赖它。比下面提到的Stab要可信得多。 Stab带来了一些C#功能和Java互操作性。不是很有用,你会获得一些C#功能,但你与之交互的是不使用这些功能的Java代码。该语言相对较为晦涩,可能已经被放弃,没有变得更好的承诺。最初由@Vns提到。 为JVM平台带来了一股清新的空气;)

ScalaKotlin等语言是运行在JVM上的非常好的语言,它们带来了一些C#程序员在Java中可能会错过的功能。特别是Kotlin在JVM世界中感觉像是一个合理的替代品。Scala可能对于一个程序员来说太大了,在短时间内难以适应。

Mono

这当然也是一个选择。如果Mono可以直接运行,为什么要转换成JVM呢。首先由@ferhrosa提到。

纽约 — 2014年11月12日 — 微软公司周三通过开源整个服务器端.NET堆栈并将.NET扩展到Linux和Mac OS平台,加强了跨平台开发者体验方面的承诺。

根据这篇新闻稿,Visual Studio 2015将添加对Linux/Mono的支持。

这是Mono项目人员关于.NET源代码集成的博客(2014年11月)。

.NET Core

这是由Microsoft管理的Windows/Linux多平台版本的.Net的一部分。详情请查看https://github.com/dotnet/core

结论

现在需要尝试使用这些工具/框架,看看是否存在阻力。原作者想要在JVM中使用C#编写代码,使用Grasshopper可能会非常不错。

但如果目标是将C#和Java世界的库混合在一个代码库中,可能效果不太好。

参考资料

http://blog.pluralsight.com/new-course-making-java-and-c-work-together-jvm-and-net-clr-interop


非常好的答案!作为一名C#开发人员,不喜欢过渡到Java(没有属性怎么活?!),并对Scala持怀疑态度,这篇文章真正清晰地阐述了选项。 - Gilthans

9

编写从IL到字节码的转换器可能会更简单。这样,您将自动获得对JVM上任何.NET语言的支持。

然而,这是一个如此明显的想法,如果还没有完成,那么它可能非常困难,或者很难做得好/有用。


7
你会遇到我列出的大多数问题 - 不同的通用等。 - Jon Skeet
8
这正是Grasshopper所做的(请参见@alex上面的答案),确实非常难做好(我曾经在Grasshopper上工作)。 - Motti

7

看看Grasshopper。它是一个基于Visual Studio的SDK和专利的.NET到Java转换器,可让您在Linux®和其他支持Java的平台上运行.NET Web和服务器应用程序。


2
你有实际的经验吗?此外,免费版本的许可证非常严格。 - Thorbjørn Ravn Andersen
13
你刚一提到“专利”这个词,我就对你不感兴趣了。唉。 - Stephen C
2
只是一些消息:Grasshopper现在是免费的(像大多数开源产品一样),没有支持和保修。 - fernacolo
1
Mainsoft 似乎已经彻底消失了,Grasshopper 的链接也不再有效。 - David Given
@DavidGiven 对我来说可以。下载链接:http://dev.mainsoft.com/Default.aspx?tabid=111&release=2.5 - Basic
1
很明显只是一点小问题而已。两个链接现在都可以使用了。不幸的是,我现在想不起来我为什么需要它了... - David Given

2

2

0

这个回答可能对你来说有点晚了,但是现在有一个新的选择。你可以尝试看看Kotlin编程语言,它提供了类似C#的语法糖,并且其语法与C#最接近,与任何非Java JVM语言相比都更为相似。它来自于JetBrains


0

我可以看到这个项目没有得到太多的热情,原因有两个。

首先需要认识到的是,在语言的实际特性方面,C# 和 Java 非常接近。C# 和 Java 不仅很接近,而且它们也朝着类似的方向发展。虽然 JVM 目前不支持某些功能,但这并不是真正的问题。你总是可以模拟缺少的部分。我想人们更喜欢等待 Java 得到更多的改进,而不是从头开始创建一个几乎和 Java 相同的东西。当移植准备好时,Java 可能已经赶上了。

其次,开发人员更喜欢使用 C# 的原因并不是它本身,而是围绕它的工具、与 C# 的双向关系以及微软对整个事情的支持。例如,C#-XAML 组合比 JavaFX 更加友好,因为 C# 和 XAML 是互相匹配的(例如,C# 中的 partial classes,在 XAML 中的 bindings 等)。在 JavaFX 上使用 C# 并不能带来太多改进。要在 JVM 上获得 C# 的体验,您需要将工具也移植过来,这是一个更大的项目。甚至 Mono 也不会费心去做。

因此,我对想要在熟悉的工具之上使用更高级语言的Java开发人员的建议是查看现有的JVM语言

Mono也是一个选择,但我一直对它持怀疑态度。尽管它是C#-.NET和跨平台的,但使用Microsoft的工具构建的东西通常不会在Mono上运行。它本质上是自己的东西。我们将看到微软表示他们将进行合作后会发生什么。


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