在最低级别,WinRT 是在 ABI 级别上定义的对象模型。它使用 COM 作为基础(因此每个 WinRT 对象都实现IUnknown
并执行引用计数),并从那里构建。与旧的 COM 相比,它确实添加了很多新概念,其中大部分直接来自 .NET - 例如,WinRT 对象模型具有委托,并且事件以 .NET 样式完成(具有委托和添加/删除订阅者方法,每个事件一个),而不是事件源和接收器的旧 COM 模型。在其他值得注意的事情中,WinRT 还具有参数化(“通用”)接口。
另一大变化是所有 WinRT 组件都有可供它们使用的元数据,就像 .NET 程序集一样。在 COM 中,你有点像 typelibs 那样,但不是每个 COM 组件都有它们。对于 WinRT,元数据包含在 .winmd 文件中 - 查看 Developer Preview 中的“C:\Program Files (x86)\Windows Kits\8.0\Windows Metadata\”。如果您四处寻找,您会发现它们实际上是没有代码的 CLI 程序集,只是元数据表。实际上,您可以使用 ILDASM 打开它们。请注意,这并不意味着 WinRT 本身是受管理的 - 它只是重复使用文件格式。
然后根据该对象模型实现了许多库 - 定义 WinRT 接口和类。再次,查看上面提到的“Windows 元数据”文件夹,看看里面有什么;或者只是在 VS 中启动对象浏览器并在框架选择器中选择“Windows 8.0”,以查看涵盖的内容。那里有很多,而且它不仅仅处理 UI - 您还可以获得诸如Windows.Data.Json
, or Windows.Graphics.Printing
, or之类的命名空间Windows.Networking.Sockets
。
然后你会得到几个专门处理 UI 的库——这些库大多是Windows.UI
or下的各种命名空间Windows.UI.Xaml
。其中很多与 WPF/Silverlight 命名空间非常相似——例如Windows.UI.Xaml.Controls
,非常匹配System.Windows.Controls
;同上Windows.UI.Xaml.Documents
等
现在,.NET 能够直接引用 WinRT 组件,就好像它们是 .NET 程序集一样。这与 COM 互操作不同 - 您不需要任何中间工件,例如互操作程序集,您只需/r
一个 .winmd 文件,并且元数据中的所有类型及其成员都对您可见,就好像它们是 .NET 对象一样。请注意,WinRT 库本身是完全本机的(因此使用 WinRT 的本机 C++ 程序根本不需要 CLR) - 将所有这些东西公开为托管的魔法在 CLR 本身内部,而且级别相当低。如果您创建一个引用 .winmd 的 .NET 程序,您会发现它实际上看起来像一个外部程序集引用 - 没有诸如类型嵌入之类的花招。
这也不是一个生硬的映射 - CLR 会尽可能将 WinRT 类型调整为它们的等价物。因此,例如 GUID、日期和 URI 分别变为System.Guid
、System.DateTime
和System.Uri
;WinRT 集合接口,例如IIterable<T>
andIVector<T>
成为IEnumerable<T>
and IList<T>
;等等。这是双向的 - 如果您有一个实现 .NET 对象IEnumerable<T>
并将其传递回 WinRT,它会将其视为IIterable<T>
.
最终,这意味着您的 .NET Metro 应用程序可以访问现有标准 .NET 库的子集,以及(本机)WinRT 库,其中一些 - 特别是Windows.UI
- 在 API 方面看起来与 Silverlight 非常相似。您仍然有 XAML 来定义您的 UI,并且您仍然处理与 Silverlight 中相同的基本概念 - 数据绑定、资源、样式、模板等。在许多情况下,可以简单地通过using
新的命名空间来移植 Silverlight 应用程序,并调整代码中调整 API 的几个地方。
WinRT 本身与 HTML 和 CSS 没有任何关系,它与 JavaScript 的关系只是在某种意义上它也暴露在那里,类似于它为 .NET 所做的事情。当您在 .NET Metro 应用程序中使用 WinRT UI 库时,您不需要处理 HTML/CSS/JS(好吧,我想,如果您真的想要,您可以托管一个WebView
控件......)。您的所有 .NET 和 Silverlight 技能在此编程模型中仍然非常重要。