6

我们正在验证方法参数在函数输入时不为空,但这不适用于Platform::String(或者Platform.String,C# 或 C++ 之间没有区别),因为它们使用空实例重载了空字符串的语义。

考虑一下,总是会抛出异常:

auto emptyString = ref new Platform::String();

// Now, emptyString.IsEmpty() will be true

if (emptyString == nullptr)
{
    throw ref new Platform::InvalidArgumentException();
}

该变量具有非空值,但==比较运算符已重载,因此将其与nullptr返回 true 进行比较,因为String实例为空。

据我所知,这使我们无法在Strings 的函数入口处进行正确的空检查。真的是这样吗?

4

2 回答 2

11

Windows 运行时中没有“空字符串”。对于字符串,“Null”和“empty”的含义相同。

尽管Platform::String使用^语法并且看起来像引用类型,但它不是:它是 Windows 运行时基本类型的投影,HSTRING. “空”HSTRING 与空 HSTRING 无法区分。

即使 aPlatform::String^看起来是“null”(例如在调试器中),也可以安全地将其视为空字符串。您可以将其用于连接、调用s->Length()等。


在 C# 中,astring可以为空(因此您可以测试它是否为空),但您永远不会string从 Windows 运行时调用中获得空值,并且您不能将空字符串作为参数传递给 Windows 运行时函数(这样做会产生ABI 边界处的异常)。

于 2012-08-31T12:38:47.053 回答
2

看来你是对的。任何设置为nullptr的字符串都被视为空字符串。如果你甚至传递nullptr给函数,你将永远不会得到NullReferenceException.

bool NullPtrTest(Platform::String^ value)
{
  return value == nullptr;
}

bool EmptyTest(Platform::String^ value)
{
  return value->IsEmpty();
}

bool ReferenceEqualsWithNullPtrTest(Platform::String^ value)
{
  return Platform::String::ReferenceEquals(nullptr, value);
}

bool EqualsWithValueTest(Platform::String^ value)
{
  return value->Equals("test");
}

//...

NullPtrTest(nullptr); // true
NullPtrTest(ref new Platform::String()); // true
NullPtrTest("test"); // false


EmptyTest(nullptr); // true - no exception
EmptyTest(ref new Platform::String()); // true
EmptyTest("test"); // false


ReferenceEqualsWithNullPtrTest(nullptr); // true
ReferenceEqualsWithNullPtrTest(ref new Platform::String()); // true
ReferenceEqualsWithNullPtrTest("test"); // false


EqualsWithValueTest(nullptr); // false - no exception
EqualsWithValueTest(ref new Platform::String()); // false
EqualsWithValueTest("test"); // true

所以,我看不出有什么办法可以找出字符串是否曾经是nullptr.

于 2012-08-31T11:39:00.523 回答