how can I < or > with two objects of any type passed as object?

  • Thread starter Thread starter ThunderMusic
  • Start date Start date
T

ThunderMusic

Hi,
I'm doing comparisons over arguments passed as Object... they can be of any
type, but must be comparable using < or >... unfortunatly, the compiler
does not give the possibility to compare 2 Object instances with < or >...
How can I do this without knowing the type of the objects?

Here's an example :

private void someMethod()
{
int m_X = 5;
float m_Y = 10.7f;

if (CompareGreaterThan(m_X, m_Y))
// DO STUFF
}

private bool CompareGreaterThan(object value1, object value2)
{
return (value1 > value2); // Here I can't do
}

thanks

ThunderMusic
 
I'm doing comparisons over arguments passed as Object... they can be of any
type, but must be comparable using < or >...

Why not use the IComparable interface instead?


Mattias
 
good idea but it does not work as "expected"...

int x = 5;
decimal y = 6;
object obj = x;
object obj2 = y;
if (obj is IComparable)
MessageBox.Show(((bool)(((IComparable)obj).CompareTo(obj2) >
0)).ToString());

I get an ArgumentException on the last line saying the argument must be a
System.Int32 even if an overload has an Object argument.... but doing this
works fine :
int x = 5;
decimal y = 6;
MessageBox.Show(((bool)(x > y)).ToString());


thanks for trying... do you have another solution?

ThunderMusic
 
* Hi,
* I'm doing comparisons over arguments passed as Object... they can be of
any
* type, but must be comparable using < or >... unfortunatly, the compiler
* does not give the possibility to compare 2 Object instances with < or >...
* How can I do this without knowing the type of the objects?
*
* Here's an example :
*
* private void someMethod()
* {
* int m_X = 5;
* float m_Y = 10.7f;
*
* if (CompareGreaterThan(m_X, m_Y))
* // DO STUFF
* }
*
* private bool CompareGreaterThan(object value1, object value2)
* {
* return (value1 > value2); // Here I can't do
* }
*
* thanks
*
* ThunderMusic
*
*

ThunderMusic,

Is this an instance where generics where help out?
For example:

private void SomeMethod()
{
int x = 5;
float y = 10.7f;

CompareGreaterThan<float>(x,y);
}

private static bool CompareGreaterThan <T> (T value1, T value2)
{
return (((ICompareable)value1).CompareTo(((Compareable)value2) > 0);
}


This worked for me.

-MH
 
The problem is that you can't use the > and < operators, because
overload selection is done at compile time, and you don't know the
types until runtime. So, operator overloading, etc, is out of the
question.

However, type coercion code is inserted at compile time, so the
convenient feature of being able to coerce int x to a decimal in order
to compare with y isn't available when you know the two types.

So, there is no out-of-the-box solution to this problem. You must write
your own run-time type checking and call the appropriate comparison
method (in the case of built-in types) and/or do smart things in the
CompareTo(object o) method for your own types.
 
In your case, you are comparing random objects, which makes things
difficult. If you know you can always cast up to a supertype (for example,
they will never overflow a single, or a double), you can cast things up and
compare. This wll work for numerics only, of course, but is an option. You
will have to perform the testing (to ensure one is not a string, for
example) and cast up.

I am not sure I have ever seen a system where random garbage needed to be
compared. It is also rare to have a properly designed system where
everything is seen as an object. Sure, it creates a very generic and loosely
coupled system, but the cost for a completely generic system can be rather
large.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

*************************************************
Think outside of the box!
*************************************************
 
Actually, we will be comparing values that come from a database to values we
provide in the code (no user interaction and classes, only value types).. So
it will mainly be byte, int, decimal and string.... but I wanted to avoid
casting my types every time a comparison is done... but if I can't do
without casting, I will cast...

thanks to everyone... if you have any other ideas, please share... ;)

ThunderMusic
 
Great Idea... I will think about it so I can be sure it can be applied
correctly in my case and I'll probably use this way... ;)

thanks a lot...

ThunderMusic
 
How can I do this without knowing the type of the objects?

You cant, but did you ever consider that you should be using stronger
typing?

So youre using values of a database, and youre pulling them out as
Objects, and comparing them to other things declared as Objects in your
code.. this is nonsense, unless you have declared every database column
as RAW..

If you have a string column, then why not use a strongly typed DataSet
that defines that column to the client as a string.. then you can jsut
say:

if(myDataRow.SomeStringColumn > "some literal in my code")


..NET is strongly typed for a reason; dont strip it away
 
actually it's because we will try to use the same set of methods for all our
comparison needs for an access control mecanism... so anything could be
compared to anything, but it will always (or almost) be value types except
in the case of isNull, isNotNull or DateTime... so that why Object was a
must, but I'll go with the generics idea, it works great...

thanks

ThunderMusic
 
Back
Top