尝试从 WinJS 读取 C# WinRT 组件中的空字符串时出现异常

Posted

技术标签:

【中文标题】尝试从 WinJS 读取 C# WinRT 组件中的空字符串时出现异常【英文标题】:Exception when trying to read null string in C# WinRT component from WinJS 【发布时间】:2012-10-19 19:13:02 【问题描述】:

我有以下情况: C# 中的数据库编译为 Windows 运行时组件。

其中一个类如下所示:

public sealed class MyData

  string TheGoods  get; private set;

UI 在 WinJS 中,我有以下内容:

var b = dataInstance.theGoods;

问题是我得到一个异常并且属性中包含以下内容:

System.ArgumentNullException 在 System.StubHelpers.HStringMarshaler.ConvertToNative(字符串托管)

看HStringMarshaler.ConvertToNative的实现,如果字符串为null好像会抛出。

这是否意味着不可能向 WinJS 公开一个空字符串?这是 WinJS 的限制还是适用于所有 WinRT?

虽然 string.Empty 确实有效,但它在语义上与 null 不同,在某些情况下,empty 是有效的并且不同于 null。

如果我将属性的类型更改为“对象”,那么它确实可以工作,但是当它真的应该是一个字符串时暴露一个对象似乎很讨厌。 有任何想法吗?文档对此非常了解

【问题讨论】:

【参考方案1】:

Windows 运行时字符串类型是值类型,没有空值。由于这个原因,.NET 投影禁止跨 Windows 运行时 ABI 边界传递空 .NET 字符串。

Windows 运行时使用的字符串类型是HSTRING 类型。虽然这种类型没有 null 值,但它确实有一个 null representation(也就是说,在 C++ 中,HSTRING s = nullptr; 是有效的)。具有空表示的HSTRING 是一个空字符串。

.NET 投影将此 null 表示转换为来自 ABI 边界的字符串的空字符串 (String.Empty),并禁止将实际的 null .NET 字符串传回 ABI 边界。

【讨论】:

那么对于 C# 来说,说类构造函数应该将字符串初始化为 string.Empty 是否安全?如果更新文档以提及它,那就太好了。 msdn.microsoft.com/en-us/library/windows/apps/… 嗯,这取决于。 .NET 字符串类型仍然是引用类型并且可能为空。只有在跨 ABI 边界传递字符串时才允许 null(即,当 .NET 字符串转换为 Windows 运行时 HSTRING 时)。所以,也许在某些情况下空字符串还是有用的,您只需要确保在字符串跨越 ABI 边界之前对其进行检查。 对...所以对于那些直接或通过接口返回给 WinRT 的类型,字符串应该初始化为空。谢谢!

以上是关于尝试从 WinJS 读取 C# WinRT 组件中的空字符串时出现异常的主要内容,如果未能解决你的问题,请参考以下文章

托管 WinRT 组件 + 虚拟方法

带有用于推送通知的 C# 后台任务的 WinJS 应用程序

SQLite WinRT 包装器在 Windows phone 8.1 项目中的处理器架构之间提供了不匹配

与WinRT组件进行操作

如何在 UWP 应用(C# 或 WinJS)中获取 Windows 10 版本(例如 1809、1903、1909、...)?

WinJS UWP javascript - 如何通过文件输入读取文件