c# - 字符串的哈希码在 .NET Core 2.1 中被破坏,但在 2.0 中有效
问题描述
我最近将我的一个项目从 .NET Core 2.0 升级到了 .NET Core 2.1。这样做之后,我的几个测试开始失败。
缩小范围后,我发现在 .NET Core 2.1 中,无法使用带有字符串排序比较选项的文化感知比较器来计算字符串的哈希码。
我创建了一个重现我的问题的测试:
[TestMethod]
public void Can_compute_hash_code_using_invariant_string_sort_comparer()
{
var compareInfo = CultureInfo.InvariantCulture.CompareInfo;
var stringComparer = compareInfo.GetStringComparer(CompareOptions.StringSort);
stringComparer.GetHashCode("test"); // should not throw!
}
我已经在几个框架上对其进行了测试,结果如下:
- .NET Core 2.0:✔ 通过
- .NET Core 2.1:✖ 失败
- .NET Framework 4.7:✖ 失败
- .NET Framework 4.6.2:✖ 失败
当失败时ArgumentException
抛出一个CompareInfo.GetHashCodeOfString
说:
标志值无效
现在,我的问题:
CompareOptions.StringSort
为什么计算哈希码时不允许使用?为什么在 .NET Core 2.0 中允许使用它?`
据我了解,CompareOptions.StringSort
仅影响字符串的相对排序顺序,不应影响哈希码计算。MSDN 说:
StringSort表示字符串比较必须使用字符串排序算法。在字符串排序中,连字符和撇号以及其他非字母数字符号位于字母数字字符之前。
解决方案
corefx 团队已确认这是 .NET Core 2.1 以及 4.6+ 的完整 .NET Framework 中的一个错误。
他们还承认,在完整框架中很难改变这种行为,因此可能会考虑在 .NET Core 2.1+ 中保持原样,以保持 .NET Core 和完整框架之间的一致性。
一种可能的解决方法是使用这样的类:
internal sealed class CultureAwareStringSortComparer : StringComparer
{
public CultureAwareStringSortComparer(
CompareInfo compareInfo,
CompareOptions options = CompareOptions.StringSort)
{
Requires.ArgNotNull(compareInfo, nameof(compareInfo));
this.SortComparer = compareInfo.GetStringComparer(options);
this.HashCodeComparer = compareInfo.GetStringComparer(
options & ~CompareOptions.StringSort);
}
internal StringComparer SortComparer { get; }
internal StringComparer HashCodeComparer { get; }
public override int Compare(string x, string y) => this.SortComparer.Compare(x, y);
public override bool Equals(string x, string y) => this.SortComparer.Equals(x, y);
public override int GetHashCode(string obj) => this.HashCodeComparer.GetHashCode(obj);
}
推荐阅读
- xcode - MacOS:是否可以在操作系统中禁用外部键盘输入?
- ruby-on-rails - Rails 测试无法运行
- ajax - 在 Epic 中测试 Post 请求
- javascript - NgClass 问题 Angular 和 D3
- android - 如何避免在任务完成之前导航到下一个?
- php - 如何在 php 中使用 PDFTK 背景?
- node.js - 将graphql apollo服务器部署到heroku
- typescript - 如何在 Typescript 中将对象与接口进行比较以查看对象是否具有正确的变量类型?
- javascript - 在我的颤动应用程序中输入时无法使键盘向上推动屏幕
- java - 如何通过 Android 的改造在相同的 KEY 中获取 Json 对象和 Json 数组