如何在 .NET 中制造空字符串?

boo*_*ife 6 .net c# string

我写了一段优化的代码,其中包含null和 空字符串的特殊情况。我现在正在尝试为此代码编写单元测试。为了做到这一点,我需要两个不同对象的空(零长度)字符串对象。像这样:

string s1, s2;
Assert.IsTrue(s1.Length == 0 && s2.Length == 0);
Assert.IsTrue(!ReferenceEquals(s1, s2));
Run Code Online (Sandbox Code Playgroud)

事实证明,大多数 .NET Framework API 字符串都在检查空结果。string.Empty在所有这些情况下,他们都会回来。例如,"x".Remove(0, 1)返回string.Empty.

如何创建新的零长度字符串对象?

Lev*_*evi 10

在 .NET 中没有真正 100% 支持的方法来制造新的零长度字符串。作为一个实现细节,现有的字符串 API 可能会尝试将零长度返回值规范化到实例string.Empty,但它们是否始终如一地执行此操作并不是开发人员应该依赖的。

特别是另外两个答案有问题:

  • string.Copy解决方案甚至包括该方法在 .NET Core 3.0 中已过时的警告。该方法很可能会从 .NET Core 的未来版本中完全删除,因此string.Copy当应用程序最终转移到新版本的运行时时,任何依赖于调用的解决方案都会中断。

  • FastAllocateString解决方案依赖于运行时内未记录的内部 API。内部 API 不能保证在版本之间保持不变。事实上,我们正在计划在下一版本的 .NET 中对字符串的行为方式进行重大更改,这项工作几乎肯定会影响这个内部 API。

因此,对于您是否有一种可靠的方法来制造新的零长度字符串实例的特定问题,答案是否定的。

如果您想在代码中对零长度字符串进行特殊处理,最好的解决方案是使用 pattern if (myString.Length == 0) { /* ... */ }。模式if (myString == string.Empty) { /* ... */ }if (myString == "") { /* ... */ }也可以工作,但他们的代码生成不会像第一个提案那样优化。

如果您想对 null 或空字符串进行特殊处理,最好的解决方案是使用现有的string.IsNullOrEmptyAPI。此方法的实现因版本,以利用当时可用的任何 JIT 优化。

来源:我是 System.String 类的主要开发人员之一。


jbt*_*ule 4

您可以使用已过时的方法String.Copy

string s1 = "";
string s2 = String.Copy("");
Assert.IsTrue(s1.Length == 0 && s2.Length == 0);
Assert.IsTrue(!ReferenceEquals(s1, s2));
Run Code Online (Sandbox Code Playgroud)