Reputation: 3716
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
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
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