C#中的泛型和继承类型

本文关键字:继承 类型 泛型 | 更新日期: 2023-09-27 18:21:04

我对处理这种特殊情况的最佳方法有点困惑。我对使用泛型还没有100%的信心。

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

我在View类的Model中有一个抽象属性,它也有两个派生类型,3DView2DView

3DModel调用View属性时,我希望返回3DView,据我所知,这就是泛型的作用(目前2D和3D版本只有自己的属性和派生类型)。

我的问题是,要做到这一点,我认为我需要将Model更改为Model<TView>,然后在3DModel2DModel中提供一个where。不过,这需要更改Model2DModel3DModel的每次使用来适应这种情况,而且它在任何地方都被使用(据我所知,包括无法将Model的实例转换为3DModel2DModel)。

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

编辑:

一些示例代码

public class View
{    
}
public class 3DView : View
{
}
public class Model
{
    public abstract View _view {get; set;}
}
public class 3DModel : Model
{
    public override 3DView _view {get; set;}
}

我收到Visual Studio错误"重写属性时无法更改返回类型"。

C#中的泛型和继承类型

您可以保留非泛型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> { }

我认为这里有两种方法。

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

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();

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

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

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

public IView View()

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

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

但是你不能得到与泛型类相同的结果。。。