我正在尝试清理现有代码库,但在对抽象类的不同派生类使用通用引用名称时遇到了问题。
例如:
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() ...
}
主要逻辑尝试使用公共(public)变量。我想创建一个新类来使用,但想以运行时多态方式使用它。由于这些类具有共同的功能,并且在需要的地方有覆盖,我希望能够创建一个实例,然后使用它:
IE: Base<T> ObjectToUse;
这样,我可以简单地引用 ObjectToUse
在下面的代码中调用常用方法。由于我继承了另一个基类的一些常用例程,我不确定我是否可以使用接口(interface)。
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
编辑:
根据我很快收到的评论(再次感谢大家)是否比删除通用 (Base<T>
) 并让所有类都是 Base() 类型更好,然后我可以定义 ObjectToUse
就像 Base ObjectToUse;
我相信。
最佳答案
这是不可能的。
通过使用需要泛型类型参数的引用,您必须给它一个。您可以在此处使用 dynamic
以便在运行时评估类型,但这是您将获得的最好结果。
即使使用模板方法模式之类的东西,您也需要指定泛型类型参数。如果您只是想要为此使用 DoSomething
方法,则需要将其提升到更高的基类(或接口(interface)),以便您可以持有对那个类型的引用,并调用该(非通用)函数。
对于您的评论,我会采取的解决方案是这样的;将公共(public)代码重构为模板方法模式在基类中。然后让“触发”函数成为非泛型基类(或接口(interface))的非泛型继承成员。现在,您可以保留对该类型的引用,并调用模板方法来引发其他调用。
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
然后:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();
关于c# 运行时多态与抽象基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26367735/