C# REPL FUN.
最近研究了不少关于 Mono 的东西。之前 Unity 热更新的几个方案 提过使用 CodeDom Compile Class on the fly 的方法,当时出现找不到 gmcs 的异常,不过后来发现是 Unity 没有设置对环境变量,设置一下就好:
var name = "PATH";
var PATH = System.Environment.GetEnvironmentVariable(name);
var MonoPath = Path.Combine(EditorApplication.applicationContentsPath, "Frameworks/Mono/bin");
var value = PATH + ":" + MonoPath;
var target = System.EnvironmentVariableTarget.Process;
System.Environment.SetEnvironmentVariable(name, value, target);
当然也可以把 gmcs.exe 和 mono.exe 打包进 Unity 项目,修改下 gmcs.bat 和 gmcs.sh 自己调用。这个做法目前在 Windows / macOS / Linux 上实验成功,但 Android 上仍然不能通过 shell 调用 gmcs,算是一个遗憾。
言归正传,除去 CodeDom 之外之前提到了可以用 Mono.CSharp.Evaluator 运行命令,然后发现了 Mono REPL,觉得挺好玩,所以用 Unity 做了一个小软件,试图在手机上还原 Mono REPL 的体验。
Mono REPL 基于 Mono.CSharp.Evaluator,可以分辨出是否为求值语句,并判断应该执行 Mono.CSharp.Evaluator.Evaluate 或 Mono.CSharp.Evaluator.Run。目前我的实现并没有这个功能,只是简单地用了一套 Material Design 的 Unity UI 结合 Mono.CSharp.Evaluator.Evaluate 执行语句。因此,如果你运行:
var x = 1 + 2;
会报错,而
var x = 1 + 2;
x;
则不会有问题,因为后一个语句最后是求值 x
的,符合 Evaluate()
需要返回值的要求。
代码补全和错误获取这两个功能还没有做,不过我很有兴趣继续研究。
软件叫 Cyan,Google Play 链接:Cyan on Google Play
软件没有 iOS 版,因为 Mono.CSharp 并不能在 AOT 条件实现,毕竟 IL2CPP 后就不能动态调用了。So, Have Fun :-)