konrad konrad - 3 months ago 8
C# Question

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.

Answer

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, ... });