使用Dictionary ContainKey始终返回true

时间:2015-06-23 14:46:59

标签: c# dictionary

我在使用Dictionary ContainsKey方法时遇到问题。虽然我正在覆盖EqualsGetHashCode方法,但我总是将值设为true。

我错过了什么?

FreeTime对象包含2个DateTime类型的变量(开始和结束)。

这是完整的课程

class FreeTime : IEquatable<FreeTime>
{ 
    #region Constants

    private const bool FirstDayOfWeekIsMonday = true;

    #endregion

    #region Private Variables

    private DateTime start;
    private DateTime end;
    private static bool TodayIsSunday = (int)DateTime.Today.DayOfWeek == 0;


    #endregion

    #region Public Fields

    public DateTime Start { get { return start; } }

    public DateTime End { get { return end; } }

    public void setStart(DateTime startValue) { start = startValue; }

    public void setEnd(DateTime EndValue) { end = EndValue; }

    #endregion

    #region Constructor

    public FreeTime()
    {
        start = DateTime.Today;
       end = DateTime.Today;
    }

    public FreeTime(DateTime s,DateTime e)
    {
        start = s;
        end = e;
    }

    #endregion

    public enum PeriodType
    {
        SingleMonth,
        AllMonths,
        InterveningMonths
    }
    public bool Equals(FreeTime other)
    {

        ////Check whether the compared object is null.  
        //if (Object.ReferenceEquals(other, null)) return false;

        //Check wether the products' properties are equal.  
        return start.Equals(other.start) && end.Equals(other.end);
    }


    public override int GetHashCode()
    {

        //Get hash code for the start field if it is not null.  
        int hashStart = start == null ? 0 : start.GetHashCode();

        //Get hash code for the end field.  
        int hashEnd = end.GetHashCode();

        //Calculate the hash code .  
        return hashStart ^ hashEnd;
    }

这就是我使用containsKey方法的方法

    Dictionary<FreeTime, string> FreeBusy = new Dictionary<FreeTime, string>();      
     if (FreeBusy.ContainsKey(intersection))      

但是我总是把值设为值

2 个答案:

答案 0 :(得分:0)

您还需要覆盖object.Equals方法。只需添加功能

public override bool Equals(object obj)
{
    if (obj is FreeTime)
        return false;
    return Equals((FreeTime)obj);
}

(您只是实现了IEquatable.Equals方法,而不是具有泛型参数的object.Equals方法)

答案 1 :(得分:0)

这里是ContainsKey函数背后的代码:

public bool ContainsKey(TKey key) {
    return FindEntry(key) >= 0;
}
// Some code
private int FindEntry(TKey key) {
    if( key == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
    }

    if (buckets != null) {
        int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
        for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
            if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
        }
    }
    return -1;
}

不可能此代码返回true:

Dictionary<FreeTime, string> FreeBusy = new Dictionary<FreeTime, string>();      
if (FreeBusy.ContainsKey(intersection))

由于字典是空的。

这段代码:

internal class FreeTime : IEquatable<FreeTime>
{
    #region Constants

    private const bool FirstDayOfWeekIsMonday = true;

    #endregion

    #region Private Variables

    private static bool TodayIsSunday = (int) DateTime.Today.DayOfWeek == 0;


    #endregion

    #region Public Fields

    public DateTime Start { get; set; }

    public DateTime End { get; set; }

    #endregion

    #region Constructor

    public FreeTime()
    {
        Start = End = DateTime.Today;
    }

    public FreeTime(DateTime s, DateTime e)
    {
        Start = s;
        End = e;
    }

    #endregion

    public enum PeriodType
    {
        SingleMonth,
        AllMonths,
        InterveningMonths
    }

    public bool Equals(FreeTime other)
    {

        ////Check whether the compared object is null.  
        //if (Object.ReferenceEquals(other, null)) return false;

        //Check wether the products' properties are equal.  
        return Start.Equals(other.Start) && End.Equals(other.End);
    }


    public override int GetHashCode()
    {

        //Get hash code for the start field if it is not null.  
        int hashStart = Start.GetHashCode();

        //Get hash code for the end field.  
        int hashEnd = End.GetHashCode();

        //Calculate the hash code .  
        return hashStart ^ hashEnd;
    }
}

在我的电脑上运行良好。