简体   繁体   English

具有抽象基类的C#运行时多态

[英]c# runtime polymorphism with abstract base class

I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class. 我正在尝试清理现有的代码库,并且在对抽象类的不同派生类使用通用引用名称时遇到麻烦。

For instance: 例如:

public abstract class Base<T> : Utilities.CommonRequiredObject
{
    protected List<T> RawContents = new List<T>();
    .
    .

    public abstract void LoadContents(List<T> Contents);        // Each Class needs to load and process differently
    protected List<T> Contents;

    public virtual void DoSomething()           // Default here for common use. Defined in Each class for its specifics (if needed)
    {
    ...
    }
    public abstract List<T> FunctionToGetContents();

}

public class FOO : Base<string>
{
    public override void DoSomething() ...
    public override List<string> FunctionToGetContents() ...
}

public class BAR : Base<byte>
{
    public override void DoSomething() ...
    public override List<byte> FunctionToGetContents() ...
}

Main Logic to try to use common variable. 尝试使用公共变量的主逻辑。 I want to create a new class to use, but want to use it then in a runtime polymorphic way. 我想创建一个新类以供使用,但是想以运行时多态的方式使用它。 As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it: 由于这些类具有通用功能,并且在需要的地方具有覆盖,因此我希望能够创建一个实例,然后使用它:

IE: Base<T> ObjectToUse;

This way, I can simply refer to the ObjectToUse in the following code and call common methods. 这样,我可以简单地在以下代码中引用ObjectToUse并调用通用方法。 As I inherited some common routines from another base class, I am not sure if I can use an interface or not. 当我从另一个基类继承了一些通用例程时,我不确定是否可以使用接口。

if(variable)
{
    FOO ObjectToUse = new FOO();
}
else
{
    BAR ObjectToUse = new BAR();
}

ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...

Edit: Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic ( Base<T> ) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; 编辑:基于我很快收到的评论(再次感谢大家),这将比删除泛型( Base<T> )并使类全部为Base()更好,然后我可以将ObjectToUse定义为Base ObjectToUse; I believe. 我相信。

This cannot be done. 无法做到这一点。

By utilizing a reference that requires a generic type parameter, you must give it one. 通过利用需要通用类型参数的引用,您必须给它一个。 You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get. 您可以在此处利用dynamic ,以便对类型进行运行时评估,但这就是您所能得到的最好的结果。

Even utilizing something like a template method pattern, you would need to specify the generic type argument. 即使利用模板方法模式之类的东西,也需要指定泛型类型参数。 If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function. 如果您只想使用DoSomething方法,则需要将其提升为更高的基类(或接口),以便您可以持有对该类型的引用,并调用该(非泛型)函数。

To your comment, the solution I would take is this; 就您的评论,我要采取的解决方案是: refactor the common code into a template method pattern within the base class . 将公共代码重构为基类中的模板方法模式。 Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). 然后,使“触发”功能成为非通用基类(或接口)的非通用继承成员。 Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur. 现在,您可以保留对该类型的引用,并调用模板方法以引起其他调用。

public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
   LoadContents(FunctionToGetContents());
   DoSomething();
}

Then: 然后:

IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();

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

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