我正在尝试为相交创建自定义 IEqualityComparer
以使用 Regex
比较字符串,但我真的不明白它在做什么。
这是来自 LinqPad 测试的代码。
比较器:
public class RegexEqualityComparer : EqualityComparer<string>
{
public RegexEqualityComparer(string pattern, RegexOptions options = RegexOptions.None)
{
_re = new Regex(pattern, options);
}
public RegexEqualityComparer(Regex re)
{
_re = re;
}
public override bool Equals(string x, string y)
{
bool res = false;
if (Object.ReferenceEquals(x, y))
res = true;
else if (x != null && y != null)
res = _re.IsMatch(x) && _re.IsMatch(y);
String.Format("RES: {0}, {1} = {2}", new object[] { x, y, res }).Dump();
return res;
}
public override int GetHashCode(string obj)
{
return obj.GetHashCode();
}
// ------------------------------------------------------------------------------------------------------------------------------------------------
private Regex _re;
}
调用方式:
RegexEqualityComparer comparer = new RegexEqualityComparer(@"^-");
new string[] { "1", "-4" }.Intersect(new string[] { "1", "-" }, comparer).Dump();
我希望这能给我 { "1", "-4"}
- 根据相等比较器,来自 set1 的两个元素都出现在 set2 中;它实际给出的是:
RES: 1, 1 = True
{ "1" }
真正让我感到困惑的是,根据比较器中的 LinqPad Dump()
,它甚至不会尝试将 -4
与任何东西进行比较 -唯一的转储是 RES: 1, 1 = True
我确定我在这里遗漏了一些明显的东西,但根本看不到它!
最佳答案
public override int GetHashCode(string obj)
{
return obj.GetHashCode();
}
如果 Equals(a, b)
则要求 GetHashCode(a) == GetHashCode(b)
。这不是由您的 EqualityComparer
保证的,这个错误意味着 Intersect()
调用找不到匹配值。
与您的 Equals
相对应的足够明智的实现是:
public override int GetHashCode(string obj)
{
if (obj == null) return 0;
if (_re.IsMatch(obj)) return 1;
return obj.GetHashCode(); // catch the reference-equals part for non-matches.
}
具有相同字符的两个字符串将被视为不相等的事实(即它认为 new string('1', 1)
不同于 "1"
) 可能是故意的,也可能是一个错误。也许 ReferenceEquals()
应该是字符串的 ==
?
关于c# - IEnumerable.Intersect 与自定义比较器,不了解行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41570983/