我有以下课程:
public class Rule {
public RuleType Type { get; }
public String Name { get; }
public Rule(String name, RuleType type) {
Name = name;
Type = type;
}
public static Boolean TryParse(String value, out Rule rule) {
// Parsing code ommited
}
}
以下是Comparer:
public class RuleEqualityComparer : IEqualityComparer<Rule> {
public Boolean Equals(Rule x, Rule y) {
return x == null && y == null ? true : x.Name == y.Name && x.Type == y.Type;
}
public Int32 GetHashCode(Rule x) {
return HashCode.Of(x.Name).And(x.Type);
}
}
如何在规则类中包含Comparer?覆盖等于?
我可以提供一个选项,以便名称比较可以是文化或案例不敏感吗?
答案 0 :(得分:1)
这里有很多内容,所以我将举例说明如何处理这个问题,然后我会尝试逐一解释。
public class Rule
{
private StringComparer _stringComparer;
public Rule(string name, RuleType type, StringComparer stringComparer = null)
{
if (name == null)
throw new ArgumentNullException("name", "name is null.");
if (type == null)
throw new ArgumentNullException("type", "type is null.");
if (stringComparer == null)
_stringComparer = StringComparer.CurrentCulture;
else
_stringComparer = stringComparer;
Name = name;
Type = type;
}
public RuleType Type { get; private set; }
public string Name { get; private set; }
public override bool Equals(object obj)
{
var rhs = obj as Rule;
if (rhs == null)
return false;
var namesEqual = _stringComparer.Equals(Name, rhs.Name);
var typesEqual = Type.Equals(rhs.Type);
if (namesEqual && typesEqual)
return true;
else
return false;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + Name.GetHashCode();
hash = hash * 23 + Type.GetHashCode();
return hash;
}
}
}
如何在规则类中包含Comparer?覆盖等于?
我不确定为什么你觉得你需要一个比较器类,但是,我会覆盖Equals甚至没有Comparer类。
我可以提供一个选项,以便名称比较可以是文化或案例不敏感吗?
我会按照其他.Net对象的示例,让您的构造函数接受StringComparer
,将Rule类的功能更改为文化或不区分大小写
如果您对GetHashCode语法感到好奇,可以在GetHashCode上查找最佳实践。这里有一个非常好的解释https://stackoverflow.com/a/2733842/4708150
对公共构造函数进行空检查也是一种很好的做法,这样你就不必在GetHashCode方法中进行空值检查,你不想在空对象上调用GetHashCode。 / p>
您可能希望在比较类型时使用Equals
,除非您通过简单的参考比较就可以了。如果您有其他相等的要求,请确保在RuleType类中重写Equals和GetHashCode。
我添加了私有的setter,我猜你只是一个错字,因为他们需要在构造函数中设置值。 编辑当我写这篇文章时,我使用的是旧的C#编译器。如果您使用的是C#6.0或更新版本,那么仅定义一个getter是read-only auto-properties的一个很好的语法,它允许您在构造函数中设置属性,但不在其他地方。