与区域性或不区分大小写的类比较

本文关键字:比较 大小写 区域性 不区 | 更新日期: 2023-09-27 17:53:40

我有以下类:

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       
  }
}

和以下比较器:

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);
  }
}

如何在Rule类中包含比较器?覆盖= ?

我是否可以提供一个选项,以便名称比较可以不区分区域性或不区分大小写?

与区域性或不区分大小写的类比较

这里有很多内容,所以我将给出一个如何处理它的示例,然后我将尝试一点一点地解释它。

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;
        }
    }
}

如何在Rule类中包含比较器?覆盖= ?

我不知道为什么你觉得你需要一个比较类,但是,是的,我会重写等号,甚至没有一个比较类。

我是否可以提供一个选项,以便名称比较可以不区分区域性或不区分大小写?

我将遵循其他。net对象的示例,并让您的构造函数采用StringComparer,将您的Rule类的功能更改为不区分文化或大小写

如果你对GetHashCode语法感到好奇,你可以在GetHashCode上查找最佳实践。这里有一个很好的解释https://stackoverflow.com/a/2733842/4708150

对你的公共构造函数进行空检查也是一个很好的做法,这样你就不必在你不想在空对象上调用GetHashCode的GetHashCode方法中进行空检查。

在比较类型时,您可能希望使用Equals,除非您可以使用简单的引用比较。如果你对相等有其他要求,确保你在RuleType类中重写了Equals和GetHashCode。

我添加了私有setter,我猜这只是你的一个错别字,因为它们需要在构造函数内部设置值。编辑当我写这个的时候,我正在使用一个旧的c#编译器。如果你使用的是c# 6.0或更新版本,只定义getter是只读自动属性的好语法,它允许你在构造函数中设置属性,但不能在其他地方设置。