Hi.
The problem you have is that your class (which essentially
is re-inventing the TypedValue class) doesn't know how to
compare itself to another instance of itself.
Ignoring for a moment, the larger question of why you are
implementing a class that is essentially the same as TypedValue
(which already knows how to compare itself to itself), if you
wanted to do it (which you shouldln't), here's a simple example
that shows how it is done, and also shows why you don't need
to do it
namespace ComplexComparisonDemo
{
// essentially, a re-invention of TypedValue,
// which also knows how to perform a value
// comparison to other instances of itself:
public struct MyTypedValue
{
public MyTypedValue( int type, object value )
{
m_type = type;
m_value = value;
}
private int m_type;
private object m_value;
public static bool operator ==( MyTypedValue a, MyTypedValue b )
{
return a.m_type == b.m_type && a.m_value.Equals(b.m_value);
}
public static bool operator !=( MyTypedValue a, MyTypedValue b )
{
return !( a == b );
}
public override bool Equals( object obj )
{
if( obj is MyTypedValue )
return this == (MyTypedValue) obj;
else
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public static class CompareDemo
{
[CommandMethod("COMPARE_MYTYPEDVALUES")]
public static void Compare_MyTypedValue()
{
Editor e = AcadApp.DocumentManager.MdiActiveDocument.Editor;
List<MyTypedValue> list = new List<MyTypedValue>();
list.Add( new MyTypedValue( (int) DataType.String, "a string" ) );
list.Add( new MyTypedValue( (int) DataType.Long, 99 ) );
list.Add( new MyTypedValue( (int) DataType.Double, 44.02 ) );
// The data we'll search for:
MyTypedValue itemToFind = new MyTypedValue( (int) DataType.Long, 99 );
if( list.Contains( itemToFind ) )
e.WriteMessage( "\nitem found." );
else
e.WriteMessage( "\nitem not found." );
}
// And this shows why you really don't need
// a TypedValue-lookalike class like the above,
// to start with:
[CommandMethod("COMPARE_TYPEDVALUES")]
public static void Compare_TypedValue()
{
Editor e = AcadApp.DocumentManager.MdiActiveDocument.Editor;
// An array of typed values to search in:
TypedValue[] values = new TypedValue[] {
new TypedValue((int) DataType.String, "a string"),
new TypedValue((int) DataType.Long, 99),
new TypedValue((int) DataType.Double, 44.02) };
// The data we'll search for:
TypedValue itemToFind = new TypedValue( (int) DataType.Long, 99 );
// Here's a way to get a stongly typed list of
// TypedValues from an array, which you can
// then call .Contains on:
List<TypedValue> list = new List<TypedValue>( values );
if( list.Contains( itemToFind ) )
e.WriteMessage( "\nitem found in List<TypedValue>" );
else
e.WriteMessage( "\nitem not found in List<TypedValue>" );
// Here's another way, which is cool because it doesn't
// make a copy of the input array, rather it just wraps
// an ArrayList around the existing array:
ArrayList arrayList = ArrayList.Adapter( values );
if( arrayList.Contains( itemToFind ) )
e.WriteMessage( "\nitem found in ArrayList" );
else
e.WriteMessage( "\nitem not found in ArrayList" );
}
}
}
I'm assuming that you're mostly doing this for the sake
of learning, which is fine, but looking at your endeavour
from a more practicle perspective, you are probably not
going to gain much by implementing a 'remove duplicate'
function for LISP, in .NET, unless you do it right.
IMHO, 'do it right' , means:
1. Eliminate your class, and use the array of TypedValue[]
returned by ResultBuffer.AsArray(), directly (you can use
either of the techniques shown in the code example, to
convert to a List<TypedValue> or ArrayList, that you can
then call Contians() or BinarySearch() on).
2. Sort the input array of TypedValues (by the datatype,
and the datavalue).
To do that, you must implement an IComparer that will be
able to compare two TypedValues. The comparer would
first compare the datatype member of 2 TypedValues, and
if they're not equal, return the reuslt of the comparison,
else if the datatype members are equal, then it would just
return the result of comparing the 2 datavalue members.
3. Use BinarySearch() to find existing elements in the list,
rather than Contains(), because the former is much faster
(at the cost of requiring the list to be sorted once). If
the input list is large, this will result in a major performance
improvement over a linear search using Contains().
Taking that approach should give you an implemention for
removing list duplicates, that's faster than any LISP-based
solution. But, also remember that you can't pass it any type
of LISP data, and *never* pass it a selection set (you would
not believe what happens when you do
.