简体   繁体   English

在强制转换为基类的对象上调用派生类方法

[英]calling a derived class method on a object cast to base class

I have a base class Element and a derived class ViewSheet . 我有一个基类Element和一个派生类ViewSheet When I am collecting all of my ViewSheet objects they are being cast to Element by the collector method. 当我收集我所有的ViewSheet对象时,它们将由collector方法ViewSheetElement Now I need to call a method on each object called ViewSheet.get_Parameter() . 现在,我需要在每个称为ViewSheet.get_Parameter()对象上调用一个方法。 That method only exists on a derived class so cannot be called on Element . 该方法仅存在于派生类上,因此不能在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? 我可以通过调用Element.GetType()来找出什么派生类型,但是如何才能将该对象实际转换为ViewSheet ,然后在其上调用ViewSheet.get_Parameter()

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. 这总是返回Element对象集合,因为那是我正在处理的所有对象的基类。 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. 我可以在收集期间进行Linq强制转换,但我需要知道,根据我的类别,我将收集特定类型的对象,而我现在一开始就不知道。 Only when I actually collect all Element objects and call GetType() do I know what type I am dealing with. 只有当我实际上收集了所有Element对象并调用GetType() ,我才知道我要处理的类型。

Use as to cast AElement . 使用as AElement If the cast is successfull, PossibleViewSheet is not null and you can call the get_Parameter() 如果转换成功,则PossibleViewSheetget_Parameter()不为null,您可以调用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 实现所有必需类的接口,并将as -Operator与以下接口配合使用

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 如果您的get_Parameter()需要一个或多个参数( get_Parameter(int definition, ...) ),请添加一个具有如下参数的对象数组:

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

You are breaking all sorts of good design and OOP rules trying to do what you are doing. 您正在打破各种好的设计和OOP规则,试图做您正在做的事情。 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. 如果不是,则您的“基类”在层次结构中太低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM