18
public class Address{
    public string ContactName {get; private set;}
    public string Company {get; private set;}
    //...
    public string Zip {get; private set;}
}

個別の住所の概念を実装したいので、Equals() をオーバーライドして、すべてのフィールドで大文字と小文字を区別しない等価性をテストしました (これらは米国の住所であるため、最大のパフォーマンスを得るために InvariantCulture の代わりに Ordinal を使用しました)。

public override bool Equals(Object obj){
    if (obj == null || this.GetType() != obj.GetType())
        return false;

    Address o = (Address)obj;

    return  
    (string.Compare(this.ContactName, o.ContactName, StringComparison.OrdinalIgnoreCase) == 0) &&
    (string.Compare(this.Company, o.Company, StringComparison.OrdinalIgnoreCase) == 0)
    // ...
    (string.Compare(this.Zip, o.Zip, StringComparison.OrdinalIgnoreCase) == 0)
}

同様に GetHashCode() を書きたいと思います(連結の非効率性は今のところ無視してください):

public override int GetHashCode(){
    return (this.contactName + this.address1 + this.zip).ToLowerOrdinal().GetHashCode();
}

しかし、それは存在しません。代わりに何を使用すればよいですか? それとも、Equals() メソッドで InvariantCulture を使用する必要がありますか?

(私は考え.ToLowerInvariant().GetHashCode()ていますが、InvariantCulture が同じ文字 (アクセントなど) が別のコンテキストでは異なる意味を持つと判断できないとは 100% 確信が持てません。)

4

3 に答える 3

17

2 つの等しくないオブジェクトが同じハッシュコードを持つことができます。ただし、2 つの等しいオブジェクトが異なるハッシュコードを持つことはありません。ハッシュコードに InvariantCulture を使用する場合、Equals の契約が OrdinalIgnoreCase に関して実装されている限り、それは正しいままです。

StringComparer.OrdinalIgnoreCase のドキュメントから (強調鉱山):

http://msdn.microsoft.com/en-us/library/system.stringcomparer.ordinalignorecase.aspx

OrdinalIgnoreCase プロパティによって返される StringComparer は、文字列内の文字を、インバリアント カルチャの規則を使用して大文字に変換されたかのように処理し、言語に依存しない単純なバイト比較を実行します。これは、プログラムによって生成された文字列を比較する場合、またはパスやファイル名などの大文字と小文字を区別しないリソースを比較する場合に最も適しています。

于 2012-07-13T18:13:34.200 に答える
5

System.HashCodeを使用できるようになりました

public class Address
{
    public string ContactName { get; private set; }
    public string Company { get; private set; }
    // ...
    public string Zip { get; private set; }

    public override bool Equals(object obj)
    {
        return
            obj is Address address &&
            string.Equals(ContactName, address.ContactName, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(Company, address.Company, StringComparison.OrdinalIgnoreCase) &&
            // ...
            string.Equals(Zip, address.Zip, StringComparison.OrdinalIgnoreCase);
    }

    public override int GetHashCode()
    {
        var hash = new HashCode();
        hash.Add(ContactName, StringComparer.OrdinalIgnoreCase);
        hash.Add(Company, StringComparer.OrdinalIgnoreCase);
        // ...
        hash.Add(Zip, StringComparer.OrdinalIgnoreCase);
        return hash.ToHashCode();
    }
}
于 2020-08-20T15:15:44.513 に答える