Down casting objects

T

Tem

I have classes A,B,C,D,E,F that implement InterfaceBase.

Whats the best way to down cast obj to the correct type?

Is there a more elegant way to do this than?

Public Void DoSomething(InterfaceBase obj)
{
if(obj is A)
((A)obj).MethodThatOnlyACanDo();
else if(obj is B)
((B)obj).MethodThatOnlyBCanDo();
....
}

if and else if can become confusing when more options (more parameters,
child types) are added.

Tem
 
C

cfps.Christian

I don't know that every method has to have a different name but if you
created a singular method in the base class and would override it in
the child classes with the same name you wouldn't have that problem.

I've run into a similar situation but it was because I needed to save
the objects differently so I had to know which one I was dealing with.
 
J

Jeff Louie

Tem... In addition to these suggestions, you could define an interface
IDoSomeThing and avoid the switch:

public void DoSomeThingIfPossible(InterfaceBase obj) {
if (obj is IDoSomething) {
( (IDoSomeThing)obj).DoSomething();
}
}

Regards,
Jeff
 
T

Tem

How would i do that if i have more than 1 parameter?

Public Void DoSomething(InterfaceBase obj1,InterfaceBase obj2)
{
if(obj1 is A && obj2 is A)
Method1(((A)obj1),((A)obj2);
else if(obj1 is A && obj2 is B)
Method2(((A)obj1),((B)obj2);
else if(obj1 is A && obj2 is C)
Method2(((A)obj1),((C)obj2);...

}
I have 36 possibilities, if and else if becomes very messy and lots of room
for making errors.
Im not sure how to use the method you mentioned with more than 1 parameter.
 
T

Tem

I thought that would make the problem easier to understand...

It's a chemistry problem
elements
Li, Na, K, Rb, Cs, Fr
all implement interface IAlkaliMetal.

Public Void PrepareCombine(IAlkaliMetal elem1, IAlkaliMetal elem2)
{
if(elem1is Li && elem2 is Li)
Combine(((Li)elem1),((Na)elem2);
else if(elem1is Li && elem2 is Na)
Combine(((Li)elem1),((Na)elem2);
else if(elem1is Li && elem2 is K)
Combine(((Li)elem1),((K)elem2);...
}

This is to illustrate what im trying to do, they don't really combine this
way.
Combine method for each possible input types.
Public Void Combine(Li elem1, Li elem2){....}
Public Void Combine(Li elem1, Na elem2){....}
Public Void Combine(Li elem1, K elem2){....}

so again my question is there a way to design this so i so have to use all
those if else if statement and go directly to the corresponding Combine
method
If there are three inputs then there would be 216.

Ideally, it would just know which overload method to go to.
Public Void PrepareCombine(IAlkaliMetal elem1, IAlkaliMetal elem2)
{
Combine(elem1,elem2);
}

Is there a better way to design this?

Tem
Peter Duniho said:
[...]
I have 36 possibilities, if and else if becomes very messy and lots of
room for making errors.
Im not sure how to use the method you mentioned with more than 1
parameter.

It would really help if you could explain what it is exactly you're
doing. Do you literally have 36 different methods that will be called?

It's possible that the problem can be factored down to something that's
simpler. But if all we know about the problem is that you have 36
different possible outcomes, dependent on two different variables, it's
difficult to see how you'd make it simpler than a straight enumeration of
the possibilities.

If we knew more about the problem, it's likely that there's some
characteristic of it that would allow a simpler way to implement it. But
without that information from you, we're stuck.

Pete
 
J

Jeff Louie

Off the top of my pointed head. Each AlkaliMetal _could_ implement
IAlkiliMetal.Combine as an instance method
someAlkaliMetal.Combine(someAlkiliMetal). So a particular metal would
presumably know how to combine with any other metal including itself.

The static method CombineAlkiliMetals(someAlkiliMetal,someAlkiliMetal)
could
simply checks for null parameters and then calls the appropriate
instance
method someAlkiliMetal.Combine. I can see a downside in duplication of
code
for am1.Combine(am2) and am2.Combine(am1), which, presumably, would have
the same implementation.

Regards,
Jeff
 
T

Tem

if(elem1is Li && elem2 is Li)
If elem2 is Li, why are you casting to Na?

That's a typo. sorry. should be Combine(((Li)elem1),((Li)elem2);
It's well and good to simplify your code examples, but you still need to
make sure that they are correct and compilable. I will assume that you
simply meant to write Li instead of Na here, and that you didn't intend
to leave off the required paren at the end of each method call in your
example.

sorry. typo.
That said, you still haven't really explained what these methods do. If
each possible combination really represents some different operation,
then I don't see any way out of at some point having to channel the flow
of execution down to one of those possible operations. If the
operations are specific to the combinations of the elements, then you
will at some point need some kind of comparison to resolve the
combinations into individual operations.

I haven't figured out what each Combine method will do. That's going to
be my next task. But I do want to structure my program correctly so that
I can add more code easily later and keep good maintainability.

The method Combine will perform totally different operations depending
on input type.
It's possible that you could represent these combinations in a table,
with delegates representing each method that handles the combination.
Then rather than having a bunch of if/else if statements, you could
search the table for the combination in question.

This sounds like a possible solution. Not sure how I would construct
such table and how to use delegates.
As far as extending this to combinations of three, again...what does
this operation do? With 216 combinations, do you really have 216
different methods you might call?

Yes with three inputs there will be 216 unique methods.

Thank you.
 
T

Tem

I thought of this as a possible solution but

someAlkaliMetal1.Combine(someAlkiliMetal2)

The Combine method in instance someAlkaliMetal1 would still need to
check the type of someAlkiliMetal2
 
T

Tem

I was just think the same.

This is what a 3 input parameter scenario would look like, again, each
Combine method does different things

Public Void PrepareCombine(IAlkaliMetal elem1, IAlkaliMetal elem2,
AlkaliMetal elem3)
{
if(elem1 is Li && elem2 is Li && elem3 is Li)
Combine(((Li)elem1),((Li)elem2),((Li)elem3));
else if(elem1 is Li && elem2 is Li && elem3 is Na)
Combine(((Li)elem1),((Li)elem2),((Li)elem3));
else if(elem1 is Li && elem2 is Li && elem3 is K)
Combine(((Li)elem1),((Li)elem2), ((K)elem3));...
}
 

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