C# 通用类约束,其中<;T>;是约束泛型类的类型

C# 通用类约束,其中<;T>;是约束泛型类的类型,c#,generics,model-view-controller,unity3d,C#,Generics,Model View Controller,Unity3d,也许不是最准确的标题,但有点难以描述;也许你们能帮我一下?我正在使用MVC格式编写一个游戏,我希望每个基类(控制器、模型和视图)都有一个对其附带功能的引用,形成一种三角形(即,模型有一个对定义它的控制器的引用,以及一个引用它的视图,等等)。这些类中的大部分看起来像这样: public class Model { public Controller controller; public View view; public void Connect (Controller contro

也许不是最准确的标题,但有点难以描述;也许你们能帮我一下?我正在使用MVC格式编写一个游戏,我希望每个基类(控制器、模型和视图)都有一个对其附带功能的引用,形成一种三角形(即,模型有一个对定义它的控制器的引用,以及一个引用它的视图,等等)。这些类中的大部分看起来像这样:

public class Model {
  public Controller controller;
  public View view;

  public void Connect (Controller controller, View view) {
    this.controller = controller;
    this.view = view; 
  }
}
这是可以的,但每当我打算调出一个ChildModel的控制器时,我都需要转换到适当的ChildController以获得正确的版本。我可以创建一个实用方法/getter来获取一个适当的强制转换项,但我不希望为每个子类重写这段代码。我原以为可以通过使基类泛型来解决这个问题,但现在我遇到了一个问题,新的泛型类需要引用试图定义它们的类,因此:

public class Model<V, C> where V : View<?, C> where C : Controller<?, V> {
  public Controller<?, V> controller;
  public View<?, C> view;

  public void Connect (Controller<?, V> controller, View<?, C> view) {
    this.controller = controller;
    this.view = view; 
  }
}
公共类模型,其中V:View这是我的建议。
1.您应该将控制器用作MVC模式的主要部分。控制器应该从模式中获取信息,对其进行处理,然后调用视图

这是我的控制器的基类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Inheritance.Classes
{
    public class Controller<T, U> where T : Model, new() where U : View, new()
    {
        protected T _model;
        protected U _view;

        public Controller()
        {
            this._model = new T();
            this._view = new U();
        }

        public Controller(T model, U view)
        {
            this._model = model;
            this._view = view;
        }

        public string ParentFunction()
        {
            return "I'm the parent";
        }
    }
}

看起来您将所有权与交互混淆了。所有权意味着一方拥有另一方,而互动意味着他们如何相互沟通。MVC主要定义三个参与者之间的交互,尽管可以说视图和控制器都拥有一个模型



在如图所示的代码中,类拥有属性,因此控制器类拥有视图,视图拥有控制器

var model = new Model();
var view  = new View<Controller<Model, View<Controller, Model>, ...
现在,如果要确保视图具有对控制器的引用,可以通过属性执行此操作

view.Controller = controller;
你可以无视我刚才给你看的一切——走财产注入路线。这意味着,您可以简单地执行此操作,而不是由构造函数接受依赖项,后者会对如何创建对象创建循环引用限制

var model = new Model();
var view  = new View();
var controller = new Controller();

model.View = view;
model.Controller = controller;

view.Controller = controller;
view.Model = model;

controller.View = view;
controller.Model = model;
无论使用何种方法,关键在于避免当前代码中的循环依赖性问题。大多数MVC框架都提供了丰富的数据绑定,打破了类之间的直接耦合,但是如果没有这种绑定,就必须编写一些东西或找到一些东西,或者在语言规则的限制下工作


有很多方法可以解决这个问题。当我写这篇文章时,有另一个答案发布,所以你也应该看看。

我想这就是你想要的:

public class GameModel : Model
{
    public int ID { get; set; }
}

public class GameView : View<GameModel, GameView>
{
    public float FOV { get; set; }
}

public class GameController : GameView.BaseControler
{
    // Set ID
    public GameController()
    {
        Model.ID=100;
        View.FOV=45f;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var gm = new GameModel();
        var view = new GameView();
        var ctrl = new GameController();

        view.Connect(gm, ctrl);

        Debug.WriteLine(view.Model.ID);
    }
}
公共类游戏模型:模型
{
公共int ID{get;set;}
}
公共类游戏视图:视图
{
公共浮点FOV{get;set;}
}
公共类GameController:GameView.BaseControler
{
//设置ID
公共游戏控制器()
{
模型ID=100;
视野FOV=45f;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var gm=新游戏模型();
var view=newgameview();
var ctrl=新游戏控制器();
查看.连接(gm,ctrl);
Debug.WriteLine(view.Model.ID);
}
}

公共类模型
{
}
公共类视图,其中TModel:Model,其中TView:View
{
公共TModel模型{get;private set;}
公共BaseControler控制器{get;private set;}
公共void连接(TModel模型、BaseControler控制器)
{
这个模型=模型;
这个控制器=控制器;
此.Controler.Connect(型号,此为TView);
}
公共类基址控制器
{
公共TView视图{get;private set;}
公共TModel模型{get;private set;}
公共void连接(TModel模型,TView视图)
{
这个模型=模型;
这个视图=视图;
}
}
}

相关和附带问题:您使用哪个程序或工具绘制该图表?非常感谢!我喜欢这个实现,我想我会继续前进。谢谢男人:)我很高兴这有帮助。设计、开发、共享!
public class Model
{   
}

public interface IView<M>
{
    M Model { get; }
}

public class MyView : IView<Model>
{
    public MyView(Model model)
    {
        Model = model;
    }

    public Model Model
    {
        get;
    }
}

public interface IController<V, M>
{
    M Model { get; }
    V View { get; }
}

public class MyController : IController<MyView, Model>
{
    public MyController(MyView view, Model model)
    {
        View = view;
        Model = model;
    }

    public Model Model
    {
        get;
    }

    public MyView View
    {
        get;
    }
}
class Program
{
    public static void Main()
    {
        var model      = new Model();
        var view       = new MyView(model);
        var controller = new MyController(view, model);
    }
}
view.Controller = controller;
var model = new Model();
var view  = new View();
var controller = new Controller();

model.View = view;
model.Controller = controller;

view.Controller = controller;
view.Model = model;

controller.View = view;
controller.Model = model;
public class GameModel : Model
{
    public int ID { get; set; }
}

public class GameView : View<GameModel, GameView>
{
    public float FOV { get; set; }
}

public class GameController : GameView.BaseControler
{
    // Set ID
    public GameController()
    {
        Model.ID=100;
        View.FOV=45f;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var gm = new GameModel();
        var view = new GameView();
        var ctrl = new GameController();

        view.Connect(gm, ctrl);

        Debug.WriteLine(view.Model.ID);
    }
}
public class Model
{

}

public class View<TModel,TView> where TModel : Model where TView : View<TModel, TView>
{
    public TModel Model { get; private set; }
    public BaseControler Controler { get; private set; }

    public void Connect(TModel model, BaseControler controler)
    {
        this.Model=model;
        this.Controler=controler;
        this.Controler.Connect(model, this as TView);
    }
    public class BaseControler
    {
        public TView View { get; private set; }
        public TModel Model { get; private set; }

        public void Connect(TModel model, TView view)
        {
            this.Model=model;
            this.View=view;
        }
    }
}