2

(name: string, value: long) ペアをセットに格納しようとしています。

public class NameValuePair
{
  public string name;
  public long value;
}

public NameValuePairComparer comparer = new NameValuePairComparer();
public HashSet<NameValuePair> nameValueSet = new HashSet<NameValuePair>(comparer);

2 つのペアは、名前または値が等しい場合に等しい - これは、EqualityComparer の Equals メソッドをオーバーライドする NameValuePairComparer で実装されます。

public class NameValuePairComparer : EqualityComparer<NameValuePair>
{
   public override bool Equals(NameValuePair x, NameValuePair y)
   {
      return (x.value == y.value) || (x.name == y.name);
   }

問題は次のとおりです: GetHashCode(NameValuePair obj) は、Equals が true を返す 2 つのオブジェクトに対して同じ値を返す必要があるため、指定された NameValuePair に対して、GetHashCode() は value.GetHashCode() または name.GetHashCode() のいずれかを返す必要がありますが、これを行うには両方のペアのどのフィールドが等しいかを知る必要があります。

   public override int GetHashCode(NameValuePair obj)
   {
      /* ??? */
      /* // Using unknown reference to x
        if (obj.value == x.value) return obj.value.GetHashCode();
        else if (obj.name == x.name) return obj.name.GetHashCode();
        else return base.GetHashCode(obj);
      */
   }
}

しかし、これを知ることはできません。つまり、これらのペアを格納するために HashSet を使用することも、EqualityComparer を使用することもできません。

Q: C# (.net 3.5) でハッシュベースでない set の実装はありますか?

Q: カスタムの equality comparer を使用して一意の NameValuePairs を保存するには、どのような方法がよいでしょうか?

4

1 に答える 1

6

2 つのペアは、名前または値が等しい場合に等しい

IEqualityComparer<T>これらの基準では、基本的に正しく実装できません。のドキュメントからEquals:

Equals メソッドは、再帰的、対称的、および推移的です。つまり、オブジェクトをそれ自体と比較するために使用された場合は true を返します。y と x が true の場合、2 つのオブジェクト x と y が true です。x と y が true で、y と z も true の場合、2 つのオブジェクト x と z が true です。

ペアを考えてみましょう:

x = { "A", 10 },
y = { "A", 20 },
z = { "B", 20 }

あなたは、 and は同じ名前を持っているので等しくなければならず、 and は同じ値を持っているので等しくなければならないと言っxyyますz。つまり、(推移性によって)xzは等しいはずです。

正しく実装することはできないためIEqualityComparer<T>、その正確さに依存するものは何も機能しないと期待すべきではありません。

要件をより詳細に調べると、実際には 2 つのコレクション (1 つは名前、もう 1 つは値)が必要であるか、または推移性の観点から意味をなさないことがわかると思います。

たとえば、提案した特性を持つセットがあり、上記の 3 つの要素を追加するとします。それらを { x, y, z } の順序で追加すると、単一のエントリになります。それらを { z, x, y } の順序で追加すると、最終的に 2 つになります。それはどのように便利な種類のセットですか?

于 2013-03-18T10:37:45.310 に答える