I am writing a program to set a sequence in which various objects will appear in report. The sequence is the Y position (cell) on Excel spreadsheet.
A demo part of co
The key (pun intended) to this is to create an IComparable-based class that maintains equality and hashing, but never compares to 0 if not equal. This can be done, and can be created with a couple bonuses - stable sorting (that is, values added to the sorted list first will maintain their position), and ToString() can simply return the actual key string value.
Here's a struct key that should do the trick:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace System
{
///
/// Defined in Totlsoft.Util.
/// A key that will always be unique but compares
/// primarily on the Key property, which is not required
/// to be unique.
///
public struct StableKey : IComparable, IComparable
{
private static long s_Next;
private long m_Sequence;
private IComparable m_Key;
///
/// Defined in Totlsoft.Util.
/// Constructs a StableKey with the given IComparable key.
///
///
public StableKey( IComparable key )
{
if( null == key )
throw new ArgumentNullException( "key" );
m_Sequence = Interlocked.Increment( ref s_Next );
m_Key = key;
}
///
/// Overridden. True only if internal sequence and the
/// Key are equal.
///
///
///
public override bool Equals( object obj )
{
if( !( obj is StableKey ) )
return false;
var dk = (StableKey)obj;
return m_Sequence.Equals( dk.m_Sequence ) &&
Key.Equals( dk.Key );
}
///
/// Overridden. Gets the hash code of the internal
/// sequence and the Key.
///
///
public override int GetHashCode()
{
return m_Sequence.GetHashCode() ^ Key.GetHashCode();
}
///
/// Overridden. Returns Key.ToString().
///
///
public override string ToString()
{
return Key.ToString();
}
///
/// The key that will be compared on.
///
public IComparable Key
{
get
{
if( null == m_Key )
return 0;
return m_Key;
}
}
#region IComparable Members
///
/// Compares this Key property to another. If they
/// are the same, compares the incremented value.
///
///
///
public int CompareTo( StableKey other )
{
var cmp = Key.CompareTo( other.Key );
if( cmp == 0 )
cmp = m_Sequence.CompareTo( other.m_Sequence );
return cmp;
}
#endregion
#region IComparable Members
int IComparable.CompareTo( object obj )
{
return CompareTo( (StableKey)obj );
}
#endregion
}
}