• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 164
  • Last Modified:

Design problem: How can I recognize an object's actual class when it's refered to by a variable of the object's parent class (or interface)?

I have a container class that has a property of type A.

A is an Abstract class (or it could be an Interface if the solution to this problem warrants it).

B, C, etc.... all derive from A (or again, they could all implement A, if it ends up being an interface).  This allows me to have the container class's property hold an object of type B or C or etc...

I also have an overloaded method (seperate  from all of these classes) that takes an object of these derived classes (one per class).  I want to use it like this:

Container container = new Container();
B b = new B();
container.Property = b;
Method(container.Property);

What I want to happen here is that the type of the object assigned to the property (i.e. B, C, etc...) would determine which overload of Method to use.  Instead, it's looking at it as type A, the parent class that property is declared as.

I realize what I am really asking for is dynamic casting.  I'd love to be able to right something like:

Method((container.Property.GetType())container.Property);

but that isn't allowed in C# (to my knowledge).

I suppose I could include a method in each subclass that returns an instance of itself as it's correct type.  So, for example, B would have:

public B GetObjectOfActualType()
{
return this;
}

The problem with that approach is that I can't put a stub for that method into the parent class (or interface) because each sub-type's GetObjectOfActualType method would return a different Type and you can't change the return type of a method declared in an abstract class (or interface), right?

Anyway...I hope that I have adequately described my design goal and the problem.  If not, I'll be around to clarify as needed.

Any and ALL help is appreciated.
0
dei1c3
Asked:
dei1c3
  • 3
  • 2
1 Solution
 
RoninTheCommented:
Let me give it a try...:-)
have a look at this code..
//Code: start

using System;
namespace mynamespace
{
      class A
      {            
            public int a;
            public void F() { Console.WriteLine("A.F"); }
            public virtual void G() { Console.WriteLine("A.G"); }
      }
      class B: A
      {
            public int b;
            new public void F() { Console.WriteLine("B.F"); }
            public override void G() { Console.WriteLine("B.G"); }
      }
      class Test
      {
            static void Main()
            {
                  B b = new B();
                  A a = b;
                  a.F();
                  b.F();
                  a.G();
                  b.G();
            }
      }
}
//Code: end

Output-
A.F
B.F
B.G
B.G

so you may make use of the polymorphism of oop.

suggestion:
Instead of
public B GetObjectOfActualType()
{
return this;
}

you may use
public string GetObjectNameOfActualType()
{
    return this.toString();
}

and in that case the return type would be the same, while return value would differ, which you can check at the time of execution.



0
 
dei1c3Author Commented:
It looks to me like you're suggesting two different things...yes?  Polymorphism as one possible solution and then the GetObjectNameOfActualType method as another?

If I am thinking about this correctly, using polymorphism for this would require me to take the functionality that I want to be in my overloaded Method (which is NOT part of any of these objects) and put it into the objects themselves.  Unfortunately, I can't do this because the objects (which are essentially data types) will be accessible externally to the secure area of my application and I don't want any processing functionality outside of that area.  Does that make sense?

As for the other suggestion, it's doable and in fact my current code uses something similar right now (while I try to figure out a better solution).  But since I can't use the name as a type for casting, I end  up with this:

B b = new b;
Container.Property = b;

if(Container.Property.GetObjectNameOfActualType == 'B') { Method((B)Container.Property); }
else{ if(Container.Property.GetObjectNameOfActualType == 'C') { Method((C)Container.Property);  }
etc...

This works, but it doesn't seem very elegant to me.  Maybe I am just being picky.  Heh.
0
 
RoninTheCommented:
well..let me suggest a slight variation of what you are doing right now..similar but prolly bit more elegant...

f(Container.Property is B)
    { Method((B)Container.Property); }
else if(Container.Property is C)
    { Method((C)Container.Property);  }
0
 
dei1c3Author Commented:
Hmm...yes, that is a bit more elegant, but I guess the thing I was mostly objecting to was the fact that a big if/else or switch block is exactly what I am trying to avoid.  The number of derived classes is somewhat significant (currently more than 10) and, more importantly, could grow in the future.  One of the goals of my design is to make the process of adding a new derived class as simple as possible...add the new class, add a method in the business tier, etc......but don't have to muck around with any existing code (in this case, the if/else block).

Does that make sense?
0
 
RoninTheCommented:
get your problem now...have you looked at the sample provided with the .net sdk for dynmanic type resolution...should be useful to you
path->Visual Studio .NET 2003\SDK\v1.1\Samples\Technologies\Reflection\DynamicTypeResolve
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now