作者本人是一个在 linux 和 mac 平台的软件开发者 (而非 Win 平台的软件开发者),同时 对 Win 平台的 GUI 组件包 有所了解 (WinForms, WPF)、对 linux 上的 GUI 组件包 (GUI toolkits) 有所了解 (包括 QT, GTK, Delphi),借由对于 C# (CLI 的 C# 实现) 和 GUI 图形库 的兴趣,结合 C# 在 linux 平台的历史(mono, WinForms, GTK#, Avalonia),来探索出一条 C# 语言支持的 linux 桌面软件-原生跨平台-的开发办法 (GTK#, Xamarin, Avalonia),同时 试图从微软官方的 .NET 发展方向 (现代桌面软件开发办法:XAML-based + 代码堆砌;.NET 平台:.NET core) 上,得到 最适合 linux 和 mac 的、原生跨平台 的桌面软件开发办法。
执念:
高权重:桌面软件 (而非服务器软件)
高权重:标记语言布局技术 (文本标记语言 declarative programming) (而非纯代码堆砌)
高权重:微软官方长期支持 (而非不受微软官方支持的)
高权重:C# 语言 (CLI 的 C# 实现) (而非其他语言)
高权重:GUI 组件包 的 目的 (是 原生跨平台,比如 GTK ,而非 把某一个平台作为一等公民、其它平台作为二等公民 对待)
高权重:GUI 组件包 的 成熟度
中权重:GUI 组件包 的 目的。最初目的是原生跨平台 的 GUI 组件包 (而非 最初目的是仅针对某一个平台(作为第一公民)而后开放给其他平台的 桌面软件开发办法)
中权重:源代码级别的跨平台,软件的源代码 可以在 另一个平台 编译运行 (而非 需要全部重写) [1]()
中权重:对于所谓的 某公司专有的 UI Framework (比如 苹果公司的 Cocoa, Cocoa Touch; 微软公司的 WinForms, WPF ) 持谨慎态度 (因为它们在定义 UI 的同时也定义了 UI 组件的通信方式、APP 的生命周期等 独占性细节:如果你采用它的 UI Framework 了,那么你对于 APP 生命周期这么基本的东西 都要重新学习,这是很大的学习成本 [1]() 2。而节省学习成本的办法,就是用一层 wrapper (让 wrapper 本身去处理和 UI Framework 的通信) (那么 只要这个 wrapper 可以适配到各个 UI Framework 那么 开发者学了它就可以少学很多东西). )
非执念:
低权重:社区驱动 (活跃但太新 未受到微软官方支持 等于是 野路子,比如 Avalonia, picoe/Eto, XWT; Flutter Electron )
低权重:现有 Win 平台桌面软件的代码重用性 (等于是 历史包袱)
https://en.wikipedia.org/wiki...
https://en.wikipedia.org/wiki...
https://en.wikipedia.org/wiki...
https://www.cnblogs.com/leoli...
有欺骗性的文章
https://www.hanselman.com/blo...
为什么它有欺骗性?因为它只字不提 Xamarin
https://news.ycombinator.com/...
为什么它有欺骗性?因为它只字不提 Xamarin ,而且大大宣传所谓的继承 WPF 精神 的 Avalonia ,而且,它人数众多
https://www.reddit.com/r/dotn...
为什么它有欺骗性?因为它人数众多,而且 这种问法十分自作聪明 “What would a cross-platform .NET UI Framework look like? Exploring Avalonia” 因为它在暗示 C#开发者在 Avalonia 出现之前 就没有 跨平台的 .NET UI 库了 而 Avalonia 是第一个跨平台库,是 linux-WPF,是救世主 (然而并不是。都是 Xamarin 玩剩下的)。好在有人提出了 微软在 .NET Conf 2017 的时候 就已经给出了跨平台软件的推荐办法:Xamarin
注意几个人:
骗子阵容:
- Scott Hanselman (.NET Core 核心开发之一,但是 面对跨平台软件解决方案却只字不提 Xamarin ,供职微软)(极具欺骗性 提出各种开源 GUI 组件库的假想 还扯 GTK# 扯 Avalonia ,懂装不懂?似乎在刻意讨好开源软件社区,同时大大低估(或希望别人大大低估)做出 一个跨平台 GUI 组件包 (QT, GTK 等) 的难度)
好人阵营:
- Miguel de Icaza (mono 和 Xamarin 的开创者,目前供职微软)
- David Ortinau (Xamarin 核心开发之一,了解 原生跨平台 GUI 组件包的实现难度 )
- https://www.dotnetconf.net/ag...
TL;DR
支持利用平台特定的功能,如 Windows 上的 Windows Forms 和 WPF ,以及 Xamarin 系的特定平台支持:通过 Xamarin 实现各个平台的原生支持
Support for leveraging platform-specific capabilities, such as Windows Forms and WPF on Windows and the native bindings to each native platform from Xamarin.
这就是微软的跨平台软件解决方案:Xamarin.
=
几个事实和事实释放出来的信号:
MS .NET Standard 实现方面:
可看作受到微软官方支持的 C# SDK 。三个主流 .NET Standard 实现 是 mono, .NET Framework, .NET Core
1 .NET Core (活跃期:2016-) 是 MS 强推荐的 .NET Standard 实现,目的是 取代 .NET Framework (已初步进入冷藏期)
1.1 这种取代关系的目的,仅限于在 Win 平台
1.2 MS 在 dnc 3 推出的 WPF, Winforms (System.Windows.Forms) 支持,也仅仅在 Win 平台 1
1.2.1 Winforms 和 WPF 各执自己的桌面软件开发办法
1.2.2 Winforms 背后 是 纯代码堆砌 UI (类似 Java Swing, 它是纯代码堆砌 UI) ,WPF 背后 是 标记语言布局技术 + 代码堆砌 UI (类似 Java JavaFX, 它用到了 FXML :使用 XML 呈现UI)
1.2.3 同样是 标记语言实现 UI 布局,WPF 使用 XAML ,JavaFX 使用 XML
1.2.4 XAML-based UI 的开发实现,它的实现有 WPF 、Avalonia 、Xamarin Forms 等
1.2.4.1 XAML-based UI 的 平台性:在 linux 和 mac 平台,WPF 暂不可用 ( dnc 不支持,mono 不支持),Avalonia 可用 (活跃期:2018- 1)
-
2 mono 作为一个 .NET Standard 实现 (活跃期:2005-2016 1),用于 把.NET 应用程序移植到 Linux 1 )
2.1 mono 的完备性:1 C# 编译器、JIT 编译器、Runtime、.NET 类库实现 (Winforms (System.Windows.Forms))、可视化开发工具和调试器 (MonoDevelop) 。
2.1.1 争议: Mono (创建者 Miguel de Icaza,Xamarin 公司,在 mono 活跃开发期 并不受到微软官方支持) 是否是一个跨平台的 .NET 实现 1。争议的理由是:mono 和 .NET Framework 在语言级别上,都是 CLI 的一种实现,后者 是 CLI 的超集,因为 CLI 本身仅仅有 C# 语言特性 它本身不涉及是否跨平台,没有定义特定的 GUI 组件库 (GUI 组件库 通常是 “平台敏感” 的,除非 明确说明 是 为跨平台而生(比如 GTK, QT, Delphi, Electron 1, 以及 Xamarin Forms )的,它们可被视作 “原生跨平台(并不会对哪一个平台有偏向)” )。
2.1.1.1 原生跨平台 的 GUI 组件库:GTK, QT, Delphi, Electron, Xamarin Forms, Java Swing, JavaFX
2.1.1.2 非原生跨平台 的 GUI 组件库:WinForms, WPF, Cocoa, etc.
2.1.1.3 原生跨平台 的 GUI 组件库 + 标记语言实现 UI 布局:GTK(XML), QT(QML), Delphi, Electron(HTML), Xamarin Forms (XAML), JavaFX(XML)
2.1.1.4 原生跨平台 的 GUI 组件库 + 标记语言实现 UI 布局 + C# :GTK#, QT#, Delphi, Electron, Xamarin Forms, JavaFX
2.1.2 mono 本身是否有 CLI 之外的、属于自己的 GUI 组件库?YES. 它有一套 mono flavor 的 WinForms ,在 API 调用的角度 可以在源代码级别 几乎兼容 Win 平台 的 WinForms 。
2.1.2.1 mono 是否有自己的 GUI 开发办法?YES ,即 mono flavor 的 WinForms ;在源代码级别可以兼容 Win 平台的 WinForms App.
2.1.2.2 mono WinForms 是纯代码堆砌 UI (类似 Win WinForms, Java Swing, 它是纯代码堆砌 UI)
2.1.2.3 mono 是否会发展出 兼容 XAML-based 的 UI 开发实现? mono 最新版本 1 是 目前暂无支持 XAML-based 的 官方开发实现。然而 Avalonia 作为 原生跨平台 的 GUI 组件库,可以在 mono 上使用 1 ;Xamarin Forms 作为 原生跨平台 的 GUI 组件库,可以在 mono 上使用 2 (废话,Xamarin就是mono的人马开发的)
2.2 mono 的最新版本 1
3 主流技术总结
对于三个主流 .NET Standard 实现 (mono, .NET Framework, .NET Core),各个平台的桌面软件开发办法的主流技术总结:(按照主流度排序)
对于 dotnet core, 如果想使用 标记语言布局技术 + 代码堆砌 的开发办法:
win: WPF, Xamarin Forms (原生跨平台), Avalonia (原生跨平台), GTK# (原生跨平台)
linux: GTK# (原生跨平台), Xamarin Forms (原生跨平台), Avalonia (原生跨平台)
mac: Xamarin Forms (原生跨平台), Avalonia (原生跨平台), GTK# (原生跨平台)
对于 .NET Framework, 如果想使用 标记语言布局技术 + 代码堆砌 的开发办法:
win: WPF, GTK# (原生跨平台), Xamarin Forms (原生跨平台), Avalonia (原生跨平台)
linux: -
mac: -
对于 mono, 如果想使用 标记语言布局技术 + 代码堆砌 的开发办法:
win: WPF, Xamarin Forms (原生跨平台), Avalonia (原生跨平台)
linux: GTK# (原生跨平台), Xamarin Forms (原生跨平台), Avalonia (原生跨平台)
mac: Xamarin Forms (原生跨平台), GTK# (原生跨平台), Avalonia (原生跨平台)
考虑的因素:技术是否成熟(存在多久了,活跃期何时)、开发是否方便(比如 GTK# binding 不是很方便 因为还要安装 GTK 先)
4 分析:信息失灵
为什么会出现一边倒的情况?为什么互联网上没有正确的信息?
原因一:很大一部分 dotnet core 的开发者,是 Win 开发者,他们不关心跨平台;即使关心跨平台,也想要优先保障 Win 平台 app 的软件 去 向外兼容各个平台,简言之:他们从来没有把 跨平台当作第一目标 (因为他们的 app 已经开发成了,它首先是一个 Win app ,然后是一个 跨平台 app)
原因二:就 C# 开发者而言,本身 90% 都是没有 跨平台需求的,10% 有跨平台需求 那也是跨手机平台 ( 他们会去用 Xamarin Forms )
原因三:有 跨平台桌面软件开发者 而言,本身 90% 都是会去选择 QT, GTK, Delphi 这些 老牌 “原生跨平台” 并支持标记语言布局技术的 GUI 组件库 (GUI toolkit):他们,跨平台桌面软件开发者们,没有把 C# 当作一个选项 (所以也就看不见 C# 区提供的 原生跨平台并支持标记语言布局技术的 GUI 组件库,如 Xamarin Forms, Avalonia, GTK# --- 诶 有 C++ GTK/QT 就够了 )。
原因四:软件开发本身就是一个细节很多的领域 1
原因五:有欺骗性的人 (Scott Hanselman 之流,打着微软的旗号,提跨平台软件却不提 Xamarin 懂装不懂,这个人太坏了 他失去了技术人的本分,并不能以 ‘迎合开源社区’ 作为无辜;当然他可能只是一个开源软件爱好者的缩影,这样的人千千万万
Avalonia 广告型 1 2
揣着明白装糊涂型 1 2 3 4
纯小白+大惊小怪+眼界狭小型 1 2 3 4
如数家珍 不知所云型 1 2 3
.NET Core 布道型 1
好人 1 2 3
他们一惊一乍的味 我都能闻到,一惊一乍又不了解情况 ( 有眼不识泰山 ) 所以指望什么开源社区 哈哈。和他们打交道真的很累,但可以预见的是 这会是一个长期事实 因为使用微软C#技术的人的总量太多了 (相反 像 Backbone.js 这种总量是没什么人使用的红极一时的技术 凉了也就凉了 1,而 类似 Avalonia 这种怪胎 凉凉很难 很难真的凉透 ),开源软件界带来的噪音 (人多嘴杂的开源社区,人总数多的地方,有眼不识泰山的人 自然也就会比人少的地方多;人多 聪明人就多 傻子也多 两嘴唇一碰 啥都说出来了,胡说八道需要理由吗? 已经见怪不怪了 )
信息失灵的另一个原因是:
人的目标不同。如果A的目标是 先在W平台做出一个软件,然后 把现有的软件 试图在L和M平台也可以运行(所谓的 porting 移植);B的目标是 做出一个软件,然后 在各个平台都可以运行(原软件本身就支持各个平台运行)。那么 他们选用的 SDK 会一样吗?不会的。
换句话说,如果你的目标是 让软件本身就支持各个平台运行,那么 你的选择就一定不会和 ‘先在W平台...再在L和M平台支持运行’的人的选择一样。
换句话说,如果你的目标是 开发跨平台软件,那么你就不应该使用某平台特定的 SDK (platform-specific SDK)。同时 你应该看清 “使用某平台特定的 SDK” 和 “使用跨平台SDK” 是两群人。
5
综上,对于 跨平台桌面软件开发者 + C# + 微软官方支持,最好的选择是:
操作系统:win / mac / linux
.NET Standard 实现:dotnet core
GUI 组件库:Xamarin Forms (原生跨平台) (活跃期:2013-)
不采用:Avalonia (原生跨平台) (太新)、GTK# (原生跨平台) (不方便 需要 GTK)
Xamarin Forms (活跃期:11 12 13 2 3 ) 才是赢家。它才是一个 C# 跨平台桌面软件开发者 的正确的、受到微软官方支持1 2 的选择。
这 才是 一个 C# 跨平台桌面软件开发者 应有的 关注点; Xamarin Forms 开发者圈子 才是他们应该去的圈子。
跨平台桌面软件开发者们,微软早就为你指出一条明路了:Xamarin
很可惜,这是一个只有少数人 才知道的秘密 ... 1 2
大多数 linuxer / 开源信仰者 都还在 等待 “社区支持” 的 WPF 开源方案 比如 Avalonia ,咳咳。坐井观天
当然,分心的理由也很多:mono, WPF, Avalonia, GTK# ... 这么多东西之间,隐藏着 Xamarin ,还被什么移动端的光芒掩盖了 (是为了怕出触动那些典型 Win 开发者(脑子里没有'原生跨平台'这根弦 -- 也不需要 因为可能 80% 的 C# 开发者一辈子都会在 Win 平台呆着, why bother? )的敏感神经嘛)
支持利用平台特定的功能,如 Windows 上的 Windows Forms 和 WPF ,以及 Xamarin 系的特定平台支持:通过 Xamarin 实现各个平台的原生支持
Support for leveraging platform-specific capabilities, such as Windows Forms and WPF on Windows and the native bindings to each native platform from Xamarin.
这就是微软的跨平台软件解决方案。
-