C#中的泛型和继承类型

时间:2015-11-06 14:22:32

标签: c# generics inheritance

我对处理这种特殊情况的最佳方法感到有些困惑。我对使用仿制药还没有100%的信心。

我有一个班级Model,它有两种派生类型,3DModel2DModel

我在类Model的{​​{1}}中有一个抽象属性,它还有两个派生类型View3DView

2DView调用3DModel属性时,我希望View返回,我理解这是泛型的来源(目前2D和3D版本只有他们的具有派生类型的自有属性。)

我的问题是,为了做到这一点,我想我需要将3DView更改为Model,然后在Model<TView>3DModel中提供一个位置。这需要更改2DModelModel2DModel的每次使用以适应这一点,并且它绝对用于所有地方(包括,据我所知,使其无法实现)将3DModel的实例转换为Model3DModel)。

我认为这是实现这一目标的唯一方法吗?对于这么简单的事情,似乎有很多额外的代码。

编辑:

一些示例代码

2DModel

我收到Visual Studio错误&#34;在覆盖属性时无法更改返回类型&#34;。

3 个答案:

答案 0 :(得分:4)

您可以保留非泛型Model类,并引入抽象通用Model类。

public abstract class Model<TView> : Model where TView : View
{
    public new TView _view
    {
        get { return base._view as TView; }
        set { base._view = value; }
    }
}

public class View3D : View { }

public class Model3D : Model<View3D> { }

public class View2D : View { }

public class Model2D : Model<View2D> { }

答案 1 :(得分:1)

对我来说,最好的解决方案是使用泛型类。

你有另一个解决方案(更难看),为你的视图创建一个接口,并定义你的方法View()如下:

public IView View()

然后,您最终可以在2D / 3D模型中创建特定属性:

public 2DView 2DView()
{
    return this.View() as 2DView;
}

但是你不能得到与通用类相同的结果......

答案 2 :(得分:1)

我认为这里有两种方法。

首先,您可以使用通常的继承:

public abstract class View 
{
    public abstract void Hello();
}

public class _3DView : View
{
    public override void Hello() 
    {
        Console.WriteLine("Hello from 3D View");
    }
}

public class _2DView : View
{
    public override void Hello() 
    {
        Console.WriteLine("Hello from 2D View");
    }
}

public abstract class Model
{
    public abstract View { get; }
}

public _3DModel : Model 
{
    public override View  { get { return new _3DView; } }
}

public _2DModel : Model 
{
    public override View  { get { return new _2DView; } }
}

Model model = new _3DModel();
model.View.Hello(); // have "Hello from 3D View"

Model anotherModel = new _2DModel();
anotherModel.View.Hello();  // have "Hello from 2D View"

通过这种方式,您可以多态地处理模型和视图,并且仍然可以在需要时将View投射到_3DView

或者你可以使用这样的泛型:

// Views are declared the same way

public abstract class Model<TView>
    where TView: View
{
    public abstract TView View { get; }
}

public class _3DModel : Model<_3DView>
{
    public override _3DView View { get { return new _3DView; } }
}

public class _2DModel : Model<_2DView>
{
    public override _2DView View { get { return new _2DView; } }
}

Model<_3DView> model = new _3DModel();
model.View.Hello();

泛型方法的缩小是你不能这样说的:

Model model = new _3DModel();

因为没有单一的模型父母。在我看来,在这种情况下,泛型方法毫无意义。