与文化或案例不敏感的阶级比较

时间:2016-06-30 16:02:31

标签: c#

我有以下课程:

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?覆盖等于?

我可以提供一个选项,以便名称比较可以是文化或案例不敏感吗?

1 个答案:

答案 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的一个很好的语法,它允许您在构造函数中设置属性,但不在其他地方。