假设我有一个Fruit Tree的通用类,以及一些指定的树:
abstract class FruitTree
{
public abstract String getFruitName();
}
class AppleTree : FruitTree
{
public override String getFruitName()
{
return "Apple";
}
}
class OrangeTree : FruitTree
{
public override String getFruitName()
{
return "Orange";
}
}
我想做的是创建一个果树工厂:
public static int APPLE = 0;
public static int ORANGE = 1;
public class FruitFactory
{
public List<FruitTree> getYummyFruitTrees(int type)
{
switch (type)
{
case 0:
return new List<AppleTree>();
case 1:
return new List<OrangeTree>();
default:
return null;
}
}
}
但是C#不允许这样做。怎么能这样呢?我不在乎是否有AppleTrees of OrangeTrees,我只想获得FruitTrees列表。
编辑: 我必须编辑我的问题,因为这个例子太简单了:
这个例子是为了简单而给出的,但它给出了问题的本质 - 我的问题是我有一个处理算法类,它使用较小的类作为处理元素。例如,Matrix,它使用特定类型的单元格(BaseCell)。
public class Matrix<T> where T : BaseCell
{
(...)
}
我必须开发这种算法的一种分支,它使用大部分基本代码,但也使用扩展单元格,例如:
public class ExtendedCell : BaseCell
{
(...)
}
public class SuperMatrix : Matrix<ExtendedCell>
{
(...)
}
而且,最后,我有一个这个算法的跑步者,它管理在theads等上运行它。
public class AlgRunner
{
Matrix<BaseCell> algToRun;
public AlgRunner(Matrix<BaseCell> alg)
{
algToRun = alg;
}
}
我只是想使用它的一些基类字段/方法,我不需要知道它是哪个算法分支,所以我必须使用继承而不是实现interfece。在Java中,我有更多的经验,这不是问题,但我不知道如何在这里实现它。
答案 0 :(得分:2)
从您添加的附加信息中可以看出,您无法使用具体类完成您正在寻找的内容。但是,您可以使用接口来执行此操作,前提是您不需要同时对输出和输入类型(即协方差和逆变)进行差异。
你可以构建:
public class IMatrix<out T> where T : BaseCell
{
T Cell { get; }
....
}
这里可以有类型为T的输出参数,但没有类型为T的输入参数。
或
public class IMatrix<in T> where T : BaseCell
{
void FunctionOnCell(T cell);
....
}
这里你可以有类型为T的输入参数,但没有类型为T的输出参数。
我认为,对于您的用例,协变(out)示例是您正在寻找的示例。
假设您使用了协变接口,那么即使实际的具体类是IMatrix<BaseCell>
,您的算法运行器也可以接受Matrix<ExtendedCell>
类型的参数。
public class AlgRunner
{
IMatrix<BaseCell> algToRun;
public AlgRunner(IMatrix<BaseCell> alg)
{
algToRun = alg;
}
}
有关创建协变和逆变接口的更多详细信息,请参阅https://msdn.microsoft.com/en-us/library/dd997386.aspx
答案 1 :(得分:-3)
这个应该有帮助
public IEnumerable<FruitTree> getYummyFruitTrees(int type)
{
switch (type)
{
case 0:
return new List<AppleTree>();
case 1:
return new List<OrangeTree>();
default:
return null;
}
}