Q:

"The given key was not present in the dictionary" - But it is

So this seems like a problem that comes up a reasonable amount (Based on questions with the same title), but i'm stumped by my occurrence.
I have inherited code, and I'm really confused by an error I'm getting
I have an object 
FiscalSamplingPoint currentPoint

pretty basic definition
public sealed class FiscalSamplingPoint : SamplingPoint, IComparable<FiscalSamplingPoint>, IEquatable<FiscalSamplingPoint>
{
    private readonly int _fiscalYear;
    private readonly int _periodNumber;
    private readonly FiscalPeriodType _periodType;

...
}

FiscalPeriodType is an enum
I have a SortedList (unsure why they are using it as a dictionary) "absolutes" of key FiscalSamplingPoint.
SortedList<FiscalSamplingPoint, PeriodsRepositoryRange>

on a specific currentPoint it throws the given key not present exception, and as excepted,
absolutes.containsKey(currentPoint) 

is false (visual studio 2010 watch debugger)
However, we have overriden GetHashCode and Equals.
and again using visual studio's watch debugger I do
currentPoint.GetHashCode 

and 
(new System.Collections.Generic.System_DictionaryDebugView<TR.API.Common.FiscalSamplingPoint,TR.API.Common.PeriodsRepositoryRange>(absolutes)).Items[3].Key.GetHashCode()

and both return the same result (62234 to be exact)
and 
currentPoint.Equals((new System.Collections.Generic.System_DictionaryDebugView<TR.API.Common.FiscalSamplingPoint,TR.API.Common.PeriodsRepositoryRange>(absolutes)).Items[3].Key)

returns true.
I really have no clue at this point what could be the issue.  any pointers would be appreciated.
edit: here are relevant functions
public bool Equals(FiscalSamplingPoint obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    return InternalEquals(obj);
}

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != typeof (FiscalSamplingPoint)) return false;
        return InternalEquals((FiscalSamplingPoint) obj);
}

private bool InternalEquals(FiscalSamplingPoint obj)
{
    return _fiscalYear == obj.FiscalYear && _periodNumber == obj.PeriodNumber && _periodType == obj.PeriodType;
}

public override int GetHashCode()
{
    return 31*_fiscalYear + 53*_periodNumber + 13*(int) _periodType;
}

For IComparable we have a few functions that work together
    public int CompareTo(FiscalSamplingPoint other)
    {
        if (other == null)
        {
            throw new ApplicationException("Other object is null");
        }

        if (this > other)
        {
            return 1;
        }
        if (Equals(other))
        {
            return 0;
        }
        return -1;
    }

    public static bool operator <(FiscalSamplingPoint point1, FiscalSamplingPoint point2)
    {
        if (point1._periodType < point2._periodType)
            return true;

        if (point1._fiscalYear < point2._fiscalYear)
            return true;

        if (point1._fiscalYear == point2._fiscalYear)
            return point1.PeriodNumber < point2.PeriodNumber;

        return false;
    }

    public static bool operator >(FiscalSamplingPoint point1, FiscalSamplingPoint point2)
    {
        if (point1._periodType > point2._periodType)
            return true;

        if (point1._fiscalYear > point2._fiscalYear)
        {
            return true;
        }
        if (point1._fiscalYear == point2._fiscalYear)
        {
            return point1.PeriodNumber > point2.PeriodNumber;
        }

        return false;
    }

A:

Implementation of < and > operators is the reason that the absolutes.containsKey(currentPoint) returns false even when the key is present in the list. SordedList<T,K> uses BinarySearch to look for the key in the list, but can't find it because the list is not sorted properly.
Most likely the Enum values play a major role to incorrect comparison. Their numerical value is greater than, even thought the contextual meaning might be less.
I suspect the you can change the < and > operators to something like what Will is suggesting in his answer.

