473,385 Members | 1,320 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

type casting with GetType

hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member functions
and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send Evaluate
lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().

Help most appreciated.
Cheers
dave
Nov 17 '05 #1
17 2927
If you know all the dervied objects and they are not too many,
i suggest the easiest way which is checking what type it is.

if (node is Num)
{
((Num) node).Something();
}
else if (node is AnotherDerived)
{
((AnotherDerived) node).SomethingElse();
}

or if some of the derivors share the same functions you could have another
base class on top
of Node.
if (node is ExtensionNode)
{
((ExtensionNode) node).Something();
}
or have them implement an interface or something.

If this is not an option for you, the only way is to use reflection to
dynamically call members,
but then you would need to know the name of the member to call anyway.
--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42********@dnews.tpgi.com.au...
hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member
functions and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send
Evaluate lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().

Help most appreciated.
Cheers
dave

Nov 17 '05 #2
hmmm looks like this will be a hard one. The problem is, Num will soon be
joined joined by Matrix, Vector, Complex, etc. And in groups of 2, that'll
make a lot of If statements!

Nov 17 '05 #3
You can't dynamically cast at run time.

and even if you could in an imaginary world, it would still do you no good.
one, at compile time, it'd have no idea what your type is suppose to be, and
hence you can't call any methods. two, since your nodes are different, you'd
still need a different block to handle each individual case, and therefore
you are back to where you started.

"David Sobey" wrote:
hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member functions
and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send Evaluate
lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().

Help most appreciated.
Cheers
dave

Nov 17 '05 #4
Maybe I should state my whole problem and see if anyone has any ideas. I'm
writing an equation parser, and Node is a parent class of Branch (which
links to other nodes with an operation), Num, and eventually Matrix,
complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to specify
that child nodes of branch are both Nums. This is where my casting probs
are. Eventually a branch can be linked to a multitude of types, and this
will cause hugely messy buggy code.

Any ideas appreciated.

Cheers
dave
Nov 17 '05 #5
I believe that an implementation of a vistor pattern may be the answer you
are looking for, check out:

http://www.dofactory.com/Patterns/Pa...or.aspx#_self1

It will allow you to remove messy if else ladders from your code
--
HTH

Ollie Riches
http://www.phoneanalyser.net

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a programmer
helping programmers.

"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42******@dnews.tpgi.com.au...
Maybe I should state my whole problem and see if anyone has any ideas. I'm
writing an equation parser, and Node is a parent class of Branch (which
links to other nodes with an operation), Num, and eventually Matrix,
complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to specify that child nodes of branch are both Nums. This is where my casting probs
are. Eventually a branch can be linked to a multitude of types, and this
will cause hugely messy buggy code.

Any ideas appreciated.

Cheers
dave

Nov 17 '05 #6
Hi,

I dont think that you have other options but using a switch or several if

whta is what you want after all? maybe we can propose a better solution

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42********@dnews.tpgi.com.au...
hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member
functions and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send
Evaluate lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().

Help most appreciated.
Cheers
dave

Nov 17 '05 #7
Hi,

Also take a look at the composition pattern
cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Ollie Riches" <ol**********@phoneanalyser.net> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I believe that an implementation of a vistor pattern may be the answer you
are looking for, check out:

http://www.dofactory.com/Patterns/Pa...or.aspx#_self1

It will allow you to remove messy if else ladders from your code
--
HTH

Ollie Riches
http://www.phoneanalyser.net

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a programmer
helping programmers.

"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42******@dnews.tpgi.com.au...
Maybe I should state my whole problem and see if anyone has any ideas.
I'm
writing an equation parser, and Node is a parent class of Branch (which
links to other nodes with an operation), Num, and eventually Matrix,
complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to

specify
that child nodes of branch are both Nums. This is where my casting probs
are. Eventually a branch can be linked to a multitude of types, and this
will cause hugely messy buggy code.

Any ideas appreciated.

Cheers
dave


Nov 17 '05 #8
You may want to implement some type of tokenizing pattern and loop through
the expression and parse it.

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42******@dnews.tpgi.com.au...
Maybe I should state my whole problem and see if anyone has any ideas. I'm
writing an equation parser, and Node is a parent class of Branch (which
links to other nodes with an operation), Num, and eventually Matrix,
complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to
specify that child nodes of branch are both Nums. This is where my casting
probs are. Eventually a branch can be linked to a multitude of types, and
this will cause hugely messy buggy code.

Any ideas appreciated.

Cheers
dave

Nov 17 '05 #9
Why did you design a OO system if you want to fight OO design?

What you want is lots of overloads of Evaluate(). Then, instead of
something whacky like:

if (node is Num)
{
((Num) node).Something();
}
else if (node is AnotherDerived)
{
((AnotherDerived) node).SomethingElse();
}

You merely have:

Evaluate(Num n1)
{ n1.Something(); }

Evaluate(AnotherDerived ad)
{ ad.SomethingElse(); }

Actually, what you REALLY want is to define Num & AnotherDerived so that
they both have a Something() method.

"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42********@dnews.tpgi.com.au...
hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member functions and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send Evaluate lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().

Nov 17 '05 #10
Perhaps you're one step away from a better design.

What you seem to be thinking now is, "I have many types of operands,
and one evaluator class. How do I make my evaluator class capable of
processing any kind of operand without making it grossly
overcomplicated, and having to change it for every new kind of operand
that I introduce?" Perhaps that's the wrong question.

What if you thought of it this way: "I have many types of operands, all
of which implement some basic methods and properties (so they all
derive from Node). I have many types of evaluators, all of which
implement some basic methods and poperties (so they all derive from
Evaluator)." Now your problem is to get the correct kind of Evaluator
for the kind of Node that you're trying to process.

I'm sure that if you look through Design Patterns you'll find some to
cope with this situation. I think you'll at least need some kind of
Factory: give it the Node you want to work with and it returns the
appropriate Evaluator to operate on that type of Node.

Nov 17 '05 #11
You see I can't do that because here's the def for Branch:Node:

class Branch:Node
{
public Node left;
public Node right;
public Operations operation;
public Node Evaluate(arguments here)
etc......

When i assign child nodes to a branch, for ex:

Num num=new Num();
num.val=10;
myBranch.left=num;
myBranch.right=OtherNum;

It does not then consider myBranch.left to be of type Num, just because
I assigned Num's to them. So i can't overload Evaluate because I'll only
ever have two Node's as my arguments.

Cheers and thanks
dave
Nov 17 '05 #12
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42******@dnews.tpgi.com.au...
Maybe I should state my whole problem and see if anyone has any ideas. I'm
writing an equation parser, and Node is a parent class of Branch (which
links to other nodes with an operation), Num, and eventually Matrix,
complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to
specify that child nodes of branch are both Nums. This is where my casting
probs are. Eventually a branch can be linked to a multitude of types, and
this will cause hugely messy buggy code.


I presume you are passing 3 params into your functions, 2 nodes and an
operator represented somehow? Wouldn't it be best that the objects inherited
from node should know what to do, so your code would simply be

Node1.Evaluate Node2, OperatorType

Then have the bulk of the code in Node1 and Node2? This would mean the code
could be a simple switch statement.

Michael
Nov 17 '05 #13
Whacky?

Like you would know.

What he needs is a string tokenizer.
--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"James Curran" <ja*********@mvps.org> wrote in message
news:uV**************@TK2MSFTNGP09.phx.gbl...
Why did you design a OO system if you want to fight OO design?

What you want is lots of overloads of Evaluate(). Then, instead of
something whacky like:

if (node is Num)
{
((Num) node).Something();
}
else if (node is AnotherDerived)
{
((AnotherDerived) node).SomethingElse();
}

You merely have:

Evaluate(Num n1)
{ n1.Something(); }

Evaluate(AnotherDerived ad)
{ ad.SomethingElse(); }

Actually, what you REALLY want is to define Num & AnotherDerived so that
they both have a Something() method.

"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42********@dnews.tpgi.com.au...
hi

- I have a class Node, with a child class Num, that inherits from Node.
- I have a function "Evaluate" that takes two Nodes as an argument.
- I call this function by sending it two "Num"'s. When i use
GetType().ToSTring(), it seems to be aware that the arguments it recieved
are in fact Nums, not Nodes.

- How do I cast the arguments to Nums so I can use all the member

functions
and variables, without doing
it manually, ie (Num)someVariable. I want to do this so I can send

Evaluate
lots of different childs of Node, without having complicate
my code further for each addition. I can't figure out how to do it with
GetType().


Nov 17 '05 #14
Check this out. There is a PDF on how to make an OO expression tree.
http://www.cs.wustl.edu/~schmidt/PDF...ion-trees4.pdf
If you have the OO model of classes already, sharing it with the group would
help.
It is hard to figure out what the best solution is without seeing the
classes.

"Michael C" <mc*****@NOSPAMoptushome.com.au> wrote in message
news:%2***************@TK2MSFTNGP10.phx.gbl...
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42******@dnews.tpgi.com.au...
Maybe I should state my whole problem and see if anyone has any ideas.
I'm writing an equation parser, and Node is a parent class of Branch
(which links to other nodes with an operation), Num, and eventually
Matrix, complex, vector etc.

If I evaluate a Branch, say an addition Branch linked to a Num of 2 and a
Num of 3, before I can call the overloaded operator of +, i need to
specify that child nodes of branch are both Nums. This is where my
casting probs are. Eventually a branch can be linked to a multitude of
types, and this will cause hugely messy buggy code.


I presume you are passing 3 params into your functions, 2 nodes and an
operator represented somehow? Wouldn't it be best that the objects
inherited from node should know what to do, so your code would simply be

Node1.Evaluate Node2, OperatorType

Then have the bulk of the code in Node1 and Node2? This would mean the
code could be a simple switch statement.

Michael

Nov 17 '05 #15
OK here goes **Holds breath**:

enum Operations {Add, Subtract};

class Class1
{
public class Node
{
}

class Branch:Node
{
public Node left;
public Node right;
public Operations operation;
static num evaluate (num l, num r)
{
num result=new num();
if (this.operation==operations.add)
{
result.val=l.val+r.val;
return result;
}
else
{
result.val=l.val-r.val;
return result;
}
}
}

internal class Num:Node
{
internal int val;

public static Node operator +(Num l, Num r)
{
Num result=new Num(l.val+r.val);
return result;
}
}

static void Main(string[] args)
{
Num l=new Num();
l.val=5;

Num r=new Num(6);
r.val=6;

Branch top=new Branch();
top.Type=Types.Branch;
top.left=(Num)l;
top.right=(Num)r;
top.operation=Operations.Add;

Node n=new Node();
Node dog=new Num();

n=Branch.Evaluate(top.l, top.r);
}
}
}

Num will eventually be joined by matrix, vector, complex, etc.

It spit out an error when i call evaluate, because despite top.l and
top.r pointing to nums, they are actually node types.

cheers
dave

Nov 17 '05 #16
First of all static methods such as operators (+, -) cannot be used as virtual methods and so it is hard to achieve dynamic binding.
I agree with Michael. You can create a virtual method in the base node class called Evaluate and override it in Num, Matrix etc. And Branch's evaluate simply treats left and right as nodes and calls node.Evaluate which will be bound to Num/Matrix at runtime automatically.

I have made some additional comments in your code. And I think looking at the pdf I sent earlier and remodelling your classes will help.

"David Sobey" <da********@gmail.com> wrote in message news:11**********************@o13g2000cwo.googlegr oups.com...
OK here goes **Holds breath**:

enum Operations {Add, Subtract};

class Class1 Why are all the classes nested in Class1?
{
public class Node
{
}

class Branch:Node
{
public Node left;
public Node right;
public Operations operation;
static num evaluate (num l, num r) Why make this method static? It looks like evaluate can belong to the branch obect.
{
num result=new num();
if (this.operation==operations.add)
{
result.val=l.val+r.val;
return result;
}
else
{
result.val=l.val-r.val;
return result;
}
}
}

internal class Num:Node
{
internal int val;

public static Node operator +(Num l, Num r)
{
Num result=new Num(l.val+r.val);
return result;
}
}

static void Main(string[] args)
{
Num l=new Num();
l.val=5;

Num r=new Num(6);
r.val=6;

Branch top=new Branch();
top.Type=Types.Branch; You may be able to get away with using GetType method or built-in typeof or is operators to query the run-time type of the object?
top.left=(Num)l;
top.right=(Num)r;
top.operation=Operations.Add;

Node n=new Node(); Why are are you creating a new instance of the Node here? You are assigning Branch.Evaluate's result to n anyway immediately.
Node dog=new Num();

n=Branch.Evaluate(top.l, top.r);
}
}
}

Num will eventually be joined by matrix, vector, complex, etc.

It spit out an error when i call evaluate, because despite top.l and
top.r pointing to nums, they are actually node types.

cheers
dave

Nov 17 '05 #17
"David Sobey" <ds****@NOSPAMugrad.unimelb.edu.au> wrote in message
news:42********@dnews.tpgi.com.au...
You see I can't do that because here's the def for Branch:Node:
So i can't overload Evaluate because I'll only
ever have two Node's as my arguments.


Sure you can.... You just need to be a bit more creative....

Node Node::Evaluate(Node n1, Node n2)
{ return n1.Evaluate(n2); } // polymorphically calls
Num::Evaluate(Node);

virtual Node Num:Evaluate(Node n2)
{ return n2.Evaluate(*this); } // polymorphically calls
Num::Evaluate(Num);

virtual Num Num:Evaluate(Num n1)
{
// Do Real Work here.....
return Node::EvaluateNumNum(n1, *this);
}

To expand it, say we have 3 different options:

EvaluateNumNum(Num lhs, Num rhs);
EvaluateNumMatrix(Num lhs, Matrix rhs); // Also used for Matrix & Num
EvaluateMatrixMatrix(Matrix lhs, Matrix rhs);

Then we would just need to add:

virtual Node Matrix::Evaluate(Node rhs)
{ return rhs.Evaluate(*this); } // calls either
Matrix::Evaluate(Matrix) or Num::Evaluate(Matrix)

virtual Matrix Num::Evaluate(Matrix lhs)
{ return EvaluateNumMatrix(lhs, *this); }

virtual Matrix Matrix::Evaluate(Matrix lhs)
{ return EvaluateMatrixMatrix(lhs, *this); }

virtual Matrix Matrix::Evaluate(Num lhs)
{ return EvaluateNumMatrix(*this, lhs): }
A fuller description of this technique is Item #31 in Scott Meyers's
book, "More Effective C++"


Nov 17 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Pavils Jurjans | last post by:
Hello, I am writing a data serialization routine, and need to determine the value type for each element in given hashtable. Number types should be treated in one way, string and char types in...
2
by: MattC | last post by:
Hi, How can do runtime casting? MyCollection derives from ArrayList I will store lost of different objects that all derive from the same parent class. I then want to be able to pass in the...
6
by: Jim Bancroft | last post by:
Hi everyone, I'm having some trouble with the code below. I receive a compile-time error on the second line saying "; expected": private static void myTestFunction(long myLong) { ...
3
by: Steve Teeples | last post by:
Can someone explain how to cast an object to a specific type during runtime? // This line of code tells me the objects type. System.Type type = System.Type.GetType("string of the type"); //...
3
by: Steve Teeples | last post by:
I have a method that passes in two string objects (both numerical numbers) and a string identifying their type. public bool DoCompare(string num1, string num2, string theirType) { System.Type...
11
by: Demorsy | last post by:
I want to convert a string (or object) to a primitive type. But I don't know the type to convert to at run time. For example l have variable (lets say its an int): int unknownType = 0; And a...
10
by: Bob | last post by:
This has been bugging me for a while now. GetType isn't availble for variables decalred as interface types, I have to DirectCast(somevariable, Object). In example: Sub SomeSub(ByVal...
23
by: René Nordby | last post by:
Hi there, Is there anyone that knows how to do the following? I have a class A and a class B, that 100% inherits from class A (this means that I don't have other code in class B, than...
16
by: danielbuus | last post by:
....or, to put it perhaps more communicative, something like this: Type someObjectsType = someObject.GetType(); someObjectsType newObject = new someObjectsType(); Is this possible? If so, how?...
2
by: NullQwerty | last post by:
Hey folks, So, I've got three enum types: enum enum1 enum enum2 enum enum3 And then I've got a function overloaded three times to accept each enum type: private void func(enum1 myenum){}
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.