runtime casting

R

Rich

I want to replace CSomeObject class with some kind of runtime method
that returns type CSomeObject that I can use as cast.

How do I specify type of explicit cast at runtime?

eg:

object object1 = new CSomeObject(22);
object object2 = new CSomeObject(2);


if ( ( runtime method returns class CSomeObject ) object1 > ( runtime
method returns CSomeObject ) object2 )
// ... etc


// won't work because compiler error "Operator '>' cannot be applied to
operands of type 'object' and 'object' " :

if (object1 > object)
// ...etc


Richard
 
J

Joshua Flanagan

I think you are asking 2 different questions:
1) How do I convert an object to a type that is returned at runtime
2) How do I compare 2 objects when I do not know their type at compile time?

I separate them, because I can answer each one, but not necessarily your
original question.

To convert an object to a type that is determined at runtime, you
Covert.ChangeType(). Example:

public Type RuntimeMethodReturnsSomeType(){
return typeof(CSomeObject);
}

object object1 = Convert.ChangeType( object2,
RuntimeMethodReturnsSomeType() );

Now object2 has been converted to a CSomeObject. However, it is still
stored in an 'object' variable, so you can still only perform actions
that can be performed on an object (which does not include comparisons
using >).


If you want to compare 2 objects without knowing their type, you can
cast them to IComparable.

object a = 3;
object b = 4;

if ( ((IComparable)a).CompareTo( b ) > 0 )
{
Console.WriteLine("a is greater");
}
else
{
Console.WriteLine("b is greater");
}

If you can't guarantee that the underlying type implements IComparable,
or are the same type, you may want to do some additional checking...

object a = 3;
object b = 4;

IComparable aComparable = a as IComparable;
if ( a != null && a.GetType() == b.GetType() ) {
if (a.CompareTo(b) > 0) {
// do stuff when a is greater than b
}
else {
// do stuff when b is greater (or equal) to a
}
}
else {
// do stuff when the objects cannot be compared
}


Hope this helps

Joshua Flanagan
http://flimflan.com/blog
 
R

Rich

I understand what you are getting at. I was hoping for a much simpler
solution like this:

Type t = someinstance.GetType();
if( (t)object > (t)object )
// etc

Maybe MS can add this feature in the next release of C#?

Thanks for the tips on Convert.ChangeType and IComparable.

Richard
 
B

Bruce Wood

What is the underlying problem you're trying to solve? What is that
you're trying to do? Maybe there's a better way to approach the problem
that doesn't require new language features. Post the details of your
problem, and perhaps someone here can suggest a different approach.
 
J

Joshua Flanagan

Rich said:
I understand what you are getting at. I was hoping for a much simpler
solution like this:

Type t = someinstance.GetType();
if( (t)object > (t)object )
// etc

I don't foresee that being added as a feature. In order for that to
work, the compiler would have to be able to guarantee that the >
operator is a valid operation for an object of type T. If type T can be
any type, there is no way the compiler could assert that as a valid line
of code.
It would only work if you could restrict T to being only types that
support the > comparison operation. That is exactly what you accomplish
by casting to IComparable.
 
A

Andreas Mueller

Rich said:
I understand what you are getting at. I was hoping for a much simpler
solution like this:

Type t = someinstance.GetType();
if( (t)object > (t)object )
// etc
Type t= someinstance.GetType();
//operator< with two arguments of type t
MethodInfo mi = t.GetMethod("op_LessThan", new Type[]{t, t} )
//execute op<. operators are static, so pass null for the instance
bool b = (bool)mi.Invoke(null, new object[]{object1, object2});
Maybe MS can add this feature in the next release of C#?

Thanks for the tips on Convert.ChangeType and IComparable.

Richard
This feature is senseless, as the information has to be retrieved at
runtime, not static at compile time. And as shown above, it already
works at runtime :)

HTH,
Andy
 
A

Andreas Mueller

Rich said:
I understand what you are getting at. I was hoping for a much simpler
solution like this:

Type t = someinstance.GetType();
if( (t)object > (t)object )
// etc
Type t= someinstance.GetType();
//operator< with two arguments of type t
MethodInfo mi = t.GetMethod("op_LessThan", new Type[]{t, t} )
//execute op<. operators are static, so pass null for the instance
bool b = (bool)mi.Invoke(null, new object[]{object1, object2});
Maybe MS can add this feature in the next release of C#?

Thanks for the tips on Convert.ChangeType and IComparable.

Richard
This feature is senseless, as the information has to be retrieved at
runtime, not static at compile time. And as shown above, it already
works at runtime :)

HTH,
Andy
 
R

Rich

A - Thanks for that answer. Unfortunately, I won't be able to call the
overloaded operator (eg static CSomeClass operator +(CSomeClass
a,CSomeClass b); ) through the MethodInfo.Invoke method. Same issue
with the interface method.

Richard
 
A

Andreas Mueller

Rich said:
A - Thanks for that answer. Unfortunately, I won't be able to call the
overloaded operator (eg static CSomeClass operator +(CSomeClass
a,CSomeClass b); ) through the MethodInfo.Invoke method. Same issue
with the interface method.

Richard
Can you be more specific? Operators are static methods of a type. You
example can be done like this:

using System;
using System.Diagnostics;
using System.Reflection;

namespace Xox
{
class Lulli
{
public static int operator +(Lulli e, Exception a)
{
return 42;
}
public static int operator +(Lulli e, Attribute a)
{
return 55;
}
}
class Program
{
static void Main(string[] args)
{
MethodInfo mi =
typeof(Lulli).GetMethod("op_Addition",
new Type[] {
typeof(Lulli),
typeof(Exception)
}
);

Debug.Assert(mi != null);

int i = (int)mi.Invoke(null, new object[] { new Lulli(),
new Exception() });
Debug.Assert(i == 42);
}
}
}
 
R

Rich

Here is the eg:

public class CDouble
{
private double d;
public CDouble(double d)
{
this.d = d;
}
public static CDouble operator +(CDouble d1,CDouble d2)
{
return new CDouble(d1.d + d2.d);
}
}
public class App
{

object obj1 = new CDouble(2.0);
object obj2 = new CDouble(3.33);

Type t = obj1.GetType();
MethodInfo mi = obj1.GetType().GetMethod( "operator +",new
Type[]{t,t} ); // this won't work
object obj_result = mi.Invoke( null , new object[]{ obj1 , obj2 }
);

}
 
A

Andreas Mueller

Rich said:
Here is the eg:

public class CDouble
{
private double d;
public CDouble(double d)
{
this.d = d;
}
public static CDouble operator +(CDouble d1,CDouble d2)
{
return new CDouble(d1.d + d2.d);
}
}
public class App
{

object obj1 = new CDouble(2.0);
object obj2 = new CDouble(3.33);

Type t = obj1.GetType();
MethodInfo mi = obj1.GetType().GetMethod( "operator +",new
Type[]{t,t} ); // this won't work
object obj_result = mi.Invoke( null , new object[]{ obj1 , obj2 }
);

}
Will work if you replace "operator +" with "op_Addition" ;-):

MethodInfo mi=obj1.GetType().GetMethod( "op_Addition",new Type[]{t,t});
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top