0

だから私がやりたいのはこれです

var result = dictionary.ContainsKey(Guid.Empty);

辞書が次のように定義されている場所var dictionary = new Dictionary<FooKeyClass, int>();

現在FooKeyClass、基本的には type の public プロパティを持つデータGuidです。私は Equals をオーバーライドしようとしました、私は自分自身を書いてみましたIComparer、私は継承しようとしましたIEquatable<Guid>。私が何をしても、必要な機能を得ることができないようです。これがC#でも可能かどうか教えてください。もしそうなら、どうすれば実装できますか?

残りのコードは次のとおりですが、現在のようにオーバーライドでちょっと汚れています。

public class FooKeyClass : IEquatable<Guid>
{
    public Guid Guid { get; set; }
    public string Name { get; set; }

    public bool Equals(Guid guid)
    {
        if (guid == null)
            return false;
        return Guid.Equals(guid);
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        var p = obj as FooKeyClass;
        if ((object)p == null)
            return false;

        return p.Guid.Equals(this.Guid);
    }

    public static bool operator ==(FooKeyClass a, Guid b)
    {
        if (object.ReferenceEquals(a, b))
            return true;

        if (((object)a == null) || ((object)b == null))
            return false;

        return a.Guid.Equals(b);                
    }

    public static bool operator ==(FooKeyClass a, FooKeyClass b)
    {            
        if (System.Object.ReferenceEquals(a, b))
            return true;

        if (((object)a == null) || ((object)b == null))
            return false;

        return a.Guid.Equals(b.Guid);
    }

    public static bool operator !=(FooKeyClass a, FooKeyClass b)
    {
        return !(a == b);
    }

    public static bool operator !=(FooKeyClass a, Guid b)
    {
        return !(a == b);
    }

    public override int GetHashCode()
    {
        return Guid.GetHashCode();
    }
}

/// <summary>    
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var dictionary = new Dictionary<FooKeyClass, int>();

        var savedGuid = Guid.NewGuid();
        var tmpKey = new FooKeyClass() { Guid = savedGuid, Name = "feeefeee" };
        dictionary.Add(tmpKey, 42);

        var result = tmpKey.Equals(savedGuid); // no error
        result = tmpKey == savedGuid; // no error 

        result = dictionary.ContainsKey(savedGuid); // compile errror
        result = dictionary.Contains(savedGuid); // compile errror
        result = dictionary.Contains<Guid>(savedGuid); // compile errror

    }
}
4

1 に答える 1

1

主なオプションは次の 2 つです。

  1. を使用して、実際のキーとして使用Guidする のインスタンスを作成します。FooKeyClass

    var result = dictionary.ContainsKey(new FooKeyClass(Guid.Empty));
    
  2. 辞書のタイプを に変更しますDictionary<Guid, int>

特定の目的でキーとして頻繁に使用する場合Guid.Emptyは、同等のキーを作成できるため、FooKeyClass.Empty新しいインスタンスを作成し続ける必要はありません。

yourFooKeyClassは辞書のキーとして使用されるためGetHashCode、インスタンスの作成後にメソッドの結果が変更されないようにする必要があります。現在の実装でFooKeyClass.Guidは、キーがディクショナリに追加された後にプロパティを設定すると、ハッシュ コードが変更されるため、ディクショナリのエントリが「失われます」。Guid代わりにFooKeyClass辞書のキーとして使用すると、この状況は自動的に回避されます。または、FooKeyClass.Guidプロパティのセッターを削除して、代わりにコンストラクターを使用するようにユーザーに要求することもできます。

于 2014-09-15T15:56:33.593 に答える