konrad
konrad

Reputation: 3716

calling a derived class method on a object cast to base class

I have a base class Element and a derived class ViewSheet. When I am collecting all of my ViewSheet objects they are being cast to Element by the collector method. Now I need to call a method on each object called ViewSheet.get_Parameter(). That method only exists on a derived class so cannot be called on Element.

I can find out what derived type is from calling Element.GetType() but then how can I actually cast that object to ViewSheet and then call the ViewSheet.get_Parameter() on it?

Since this happens a lot, I would need to implement some sort of generic method that could accept different base class + derived class combinations. Any ideas will be appreciated.

Example of collector method:

`ICollection<Element> allElements = 
    new FilteredElementCollector(activeDoc)
    .OfCategory(someCategory)
    .WhereElementIsNotElementType()
    .ToElements();

This always returns object collection of Element since thats the base class for all objects that I am dealing with. I could do a Linq cast during that collection but I would need to know that based on my Category I would be collecting specific type of objects which I do not now at the outset. Only when I actually collect all Element objects and call GetType() do I know what type I am dealing with.

Upvotes: 0

Views: 527

Answers (2)

Fruchtzwerg
Fruchtzwerg

Reputation: 11399

Use as to cast AElement. If the cast is successfull, PossibleViewSheet is not null and you can call the get_Parameter()

ViewSheet PossibleViewSheet = AElement as ViewSheet;

if (PossibleViewSheet != null)
{
  PossibleViewSheet.get_Parameter();
}

If you have many different concrete classes, you have to define an interface

public interface IGetParameter
{
  int get_Parameter();
}

Implement the interface to all needed classes and use the as-Operator with the interface like

IGetParameter PossibleGetParameter = AElement as IGetParameter;

if (PossibleGetParameter != null)
{
  PossibleGetParameter.get_Parameter();
}

Thrid way is to use reflection to get the method by name like

try
{
  AElement.GetType().GetMethod("get_Parameter").Invoke(AElement, null);
}
catch(Exception)
{
  //Method is not available
}

If your get_Parameter() requires one or more parameters (get_Parameter(int definition, ...)), add an object array with the paremeter(s) like

AElement.GetType().GetMethod("get_Parameter").Invoke(AElement, new object[] { definition, ... });

Upvotes: 4

SledgeHammer
SledgeHammer

Reputation: 7736

You are breaking all sorts of good design and OOP rules trying to do what you are doing. If you want to use a "base class", it should contain all the virtual methods that the derived classes need to implement. If it doesn't, your "base class" is too low on the hierarchy.

Upvotes: 0

Related Questions