Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过比较不同类型,检查字典是否包含键_C#_Collections_Equals_Iequalitycomparer_Equals Operator - Fatal编程技术网

C# 通过比较不同类型,检查字典是否包含键

C# 通过比较不同类型,检查字典是否包含键,c#,collections,equals,iequalitycomparer,equals-operator,C#,Collections,Equals,Iequalitycomparer,Equals Operator,所以我想做的是 var result = dictionary.ContainsKey(Guid.Empty); 其中dictionary定义为var dictionary=newdictionary() 现在的FooKeyClass基本上只是一些带有类型为Guid的公共属性的数据。 我尝试过重写Equals,我尝试过编写我自己的IComparer,我尝试过继承IEquatable。无论我做什么,似乎都无法获得所需的功能。有人能告诉我这在C#中是否可能,如果可能,我该如何实现它 下面是代码的其

所以我想做的是

var result = dictionary.ContainsKey(Guid.Empty);
其中dictionary定义为
var dictionary=newdictionary()

现在的
FooKeyClass
基本上只是一些带有类型为
Guid
的公共属性的数据。 我尝试过重写Equals,我尝试过编写我自己的
IComparer
,我尝试过继承
IEquatable
。无论我做什么,似乎都无法获得所需的功能。有人能告诉我这在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

    }
}
public类FooKeyClass:IEquatable
{
公共Guid Guid{get;set;}
公共字符串名称{get;set;}
公共布尔等于(Guid)
{
如果(guid==null)
返回false;
返回Guid.Equals(Guid);
}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)
返回false;
var p=作为FooKeyClass的obj;
如果((对象)p==null)
返回false;
返回p.Guid.Equals(this.Guid);
}
公共静态布尔运算符==(FooKeyClass a,Guid b)
{
if(object.ReferenceEquals(a,b))
返回true;
如果(((对象)a==null)| |((对象)b==null))
返回false;
返回a.Guid.Equals(b);
}
公共静态布尔运算符==(FooKeyClass a,FooKeyClass b)
{            
if(System.Object.ReferenceEquals(a,b))
返回true;
如果(((对象)a==null)| |((对象)b==null))
返回false;
返回a.Guid.Equals(b.Guid);
}
公共静态布尔运算符!=(FooKeyClass a,FooKeyClass b)
{
返回!(a==b);
}
公共静态布尔运算符!=(FooKeyClass a,Guid b)
{
返回!(a==b);
}
公共覆盖int GetHashCode()
{
返回Guid.GetHashCode();
}
}
///     
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
var dictionary=newdictionary();
var savedGuid=Guid.NewGuid();
var tmpKey=new FooKeyClass(){Guid=savedGuid,Name=“feeefeee”};
词典.增补(tmpKey,42);
var result=tmpKey.Equals(savedGuid);//无错误
结果=tmpKey==savedGuid;//无错误
结果=dictionary.ContainsKey(savedGuid);//编译错误
结果=dictionary.Contains(savedGuid);//编译错误
结果=dictionary.Contains(savedGuid);//编译错误
}
}

您的两个主要选项如下:

  • 使用
    Guid
    创建用作实际键的
    FooKeyClass
    实例:

    var result = dictionary.ContainsKey(new FooKeyClass(Guid.Empty));
    
  • 将词典类型更改为
    词典

  • 如果经常使用
    Guid.Empty
    作为某些特定用途的键,则可以创建等效键
    FooKeyClass.Empty
    ,这样就不必继续创建它的新实例


    请注意,由于
    FooKeyClass
    用作字典的键,因此应确保创建实例后,
    GetHashCode
    方法的结果不会更改。在当前实现中,如果在将密钥添加到字典后设置
    FooKeyClass.Guid
    属性,则字典中的条目将“丢失”,因为哈希代码会更改。如果您使用
    Guid
    而不是
    FooKeyClass
    作为字典的键,或者您可以删除
    FooKeyClass.Guid
    属性的setter,并要求用户使用构造函数,则会自动避免这种情况。

    这似乎是非常大的开销,更不用说这似乎是错误的方法。如果您进行了所有这些工作,那么将字典封装在您自己制作的自定义字典类中,并公开一个不同的ContainsKey方法来完成您正在寻找的任务,不是更容易吗?照现在的情况,你是在掩饰你的意图。它根本不包含密钥,它可能只包含包含密钥的对象。我建议从另一个角度来解决这个问题。是的,你可能是对的。只是我的固执克服了我的理性思考,在下午晚些时候编码。在自定义词典中使用附加的所需功能包装词典听起来更明智。谢谢对象的Guid永远不会更改,这至少是我的意图,而且Guid永远不会为空。不过,这只是理论上的,也是我努力追求的。我认为
    Dictionary
    也是一个可行的解决方案。