将对象添加到字典...但测试部分唯一性 [英] Adding an object to a dictionary... but testing for partial uniqueness

查看:104
本文介绍了将对象添加到字典...但测试部分唯一性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下对象,如果有重复,我想要一个字典有条件地确定。例如,在一本字典中,我只关心两个属性对于我的密钥是唯一的。在第二个字典中,我希望所有的属性都是唯一的密钥。

I have the following object and I want a dictionary to conditionally determine if there is a duplicate. For example, in one dictionary I only care about two properties being unique for my key. In a second dictionary, I want all the properties being unique for the key.

问题1:

我应该覆盖什么接口来完成这个? (例如GetHashCode,IEqualityComparer,equals运算符)

What interfaces should I override to accomplish this? (e.g. GetHashCode, IEqualityComparer, equals operator)

问题2:

如果我更改最终更改键值的属性,我该怎么办?如果我做一个字典,这可能更有用,因为.NET框架以某种方式处理这个,但我从来没有想过。

What should I do if I change a property that ultimately changes the value of the key? This is probably more relevant if I do an Dictionary since .NET framwork somehow handles this for me, but I never thought about it.

代码

public class EventData : IEqualityComparer<EventData>
{
    public string ComputerName { get; set; }
    public Guid? CategoryName { get; set; }
    public string LogName { get; set; }
    public int EventID { get; set; }
    public long? EventUniqueTracker { get; set; }

    public DateTime LastQueryDate { get; set; }
    public DateTime? DateOfRecord { get; set; }

    //public int QueryCount { get; set; }
    public int QueryCount = 0 ;//

    public string  zData { get; set; }

    public EventData(string computerName, Guid? categoryName, string logName, int eventID, long? eventUniqueTracker, int queryCount)
    {
        ComputerName = computerName;
        CategoryName = categoryName;
        LogName = logName;
        EventID = eventID;
        EventUniqueTracker = eventUniqueTracker;

        LastQueryDate = DateTime.Now;
        QueryCount = queryCount;
    }

    public EventData()
    {
    }

    public override int GetHashCode()
    {
        return GetHashCode(HashType.ZCompCatLogEventAllData);
    }
    public object GetString(HashType hType)
    {
        switch (hType)
        {
            case HashType.AComputerName:
                return ComputerName;
                break;
            case HashType.BCompAndCat:
                return new { A = ComputerName, B = CategoryName };
                break;
            case HashType.CCompCatLog:
                return new { A = ComputerName, B = CategoryName, C = LogName };
                break;
            case HashType.DCompCatLogEvent:
                return new { A = ComputerName, B = CategoryName, C = LogName, D = EventID };
                break;
            case HashType.ECompCatLogEventUserDefined1:
            case HashType.FCompCatLogEventUserDefined2:
            case HashType.ZCompCatLogEventAllData:
                return new { A = ComputerName, B = CategoryName, C = LogName, D = EventID, E = EventUniqueTracker };
            default:
                break;
        }
        return new object { };
    }

    public int GetHashCode(HashType hType)
    {
        return GetString(hType).GetHashCode();
        return 1;
    }

    public override string ToString()
    {
        return ComputerName + " " + CategoryName + " " + LogName + " " + EventID + " " + EventUniqueTracker;
    }

    public bool Equals(EventData x, EventData y)
    {
        return x.ComputerName == y.ComputerName &&
               x.CategoryName == y.CategoryName &&
               x.LogName == y.LogName &&
               x.EventID == y.EventID &&
               x.EventUniqueTracker == y.EventUniqueTracker;
    }

    public int GetHashCode(EventData obj)
    {
        EventData ci = (EventData)obj;
        // http://stackoverflow.com/a/263416/328397
        return new { A = ci.ComputerName, B = ci.CategoryName, C = ci.LogName, D = ci.EventID, E = ci.EventUniqueTracker }.GetHashCode();
    }
}


推荐答案

听起来你应该在 EventData 内部实现 IEqualityComparer< EventData> - 。创建两个单独的实现 - 一个是第一个平等的概念,一个是第二个。然后创建您的字典:

It sounds like you should be implementing IEqualityComparer<EventData> - but not within EventData itself. Create two separate implementations - one for the first notion of equality, and one for the second. Then create your dictionaries as:

var first = new Dictionary<EventData, string>(new PartialDataEqualityComparer());
var second = new Dictionary<EventData, string>(new FullDataEqualityComparer());

或者你想将第二种情况视为 EventData ,在这种情况下,您可以使 EventData 实现 IEquatable< EventData> 在创建第二个字典时指定比较器。

Or perhaps you want to treat the second case as the "natural" equality for EventData, in which case you could make EventData implement IEquatable<EventData> and not specify a comparer when creating the second dictionary.

基本上,您实现 IEquatable< T> 来说一个实例这种类型的能够将本身 T 的实例进行比较,而实现 IEqualityComparer< T> 说这种类型的实例能够比较 T 的任何两个实例。

Basically, you implement IEquatable<T> to say "an instance of this type is capable of comparing itself against an instance of T" whereas you implement IEqualityComparer<T> to say "an instance of this type is capable of comparing any two instances of T".


如果我更改最终更改密钥值的属性,该怎么办?

What should I do if I change a property that ultimately changes the value of the key?

你填充了,基本上您将不会(或至少可能不会)在您的字典中再次找到该键。你应该尽可能仔细地避免这种情况。就个人而言,我通常会发现字典键的好候选人是也是不可变的好候选人。

You're stuffed, basically. You won't (or at least probably won't) be able to find that key again in your dictionary. You should avoid this as carefully as you possibly can. Personally I usually find that classes which are good candidates for dictionary keys are also good candidates for immutability.

这篇关于将对象添加到字典...但测试部分唯一性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆