lbs*_*str 12 asp.net oop razor asp.net-mvc-3
大图:
我发现了Razor似乎是一个限制,我无法想出一个好方法.
玩家们:
假设我有一个这样的模型:
public abstract class BaseFooModel<T>
where T : BaseBarType
{
public abstract string Title { get; } // ACCESSED BY VIEW
public abstract Table<T> BuildTable();
protected Table<T> _Table;
public Table<T> Table // ACCESSED BY VIEW
{
get
{
if (_Table == null)
{
_Table = BuildTable();
}
return _Table;
}
}
}
Run Code Online (Sandbox Code Playgroud)
像这样的子类:
public class MyFooModel : BaseFooModel<MyBarType>
{
// ...
}
public class MyBarType : BaseBarType
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我希望能够传递MyFooModel到这样定义的剃刀视图:
// FooView.cshtml
@model BaseFooModel<BaseBarType>
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.我得到一个运行时错误,说FooView预期BaseFooModel<BaseBarType>但得到MyFooModel.回想一下,MyFooModel来自BaseFooModel<MyBarType>和MyBarType继承自的BaseBarType.
我尝试过的:
我在非剃刀的土地上尝试了这一点,看看它是否属实,这是真的.我不得不在视图中使用模板参数来使其工作.这是非剃须刀的观点:
public class FooView<T>
where T : BaseBarType
{
BaseFooModel<T> Model;
public FooView(BaseFooModel<T> model)
{
Model = model;
}
}
Run Code Online (Sandbox Code Playgroud)
使用该结构,以下工作可行:
new FooView<MyBarType>(new MyFooModel());
Run Code Online (Sandbox Code Playgroud)
我的问题:
我怎么能用Razor做到这一点?我怎样才能像我一样传递类型FooView?
我不能,但有什么方法可以解决这个问题吗?我能以某种方式实现相同的架构吗?
如果我能提供更多信息,请告诉我.我正在使用.NET 4和MVC 3.
编辑:
目前,我只是为每个子类添加一个剃刀视图BaseFooModel<BaseBarType>.我对此并不感到兴奋,因为每次添加新模型时我都不想创建新视图.
另一种选择是只取的事实,我的优势是能够得到正规的C#类这方面的工作没有剃须刀.我可以让我的剃刀查看@inheritsc#视图,然后调用一些渲染方法.我不喜欢这个选项,因为我不喜欢有两种渲染html的方法.
还有其他想法吗?我知道当我使用Foo和给出类名时很难理解问题的上下文Bar,但由于它有点敏感,所以我无法提供太多信息.我为此道歉.
到目前为止,我使用本杰明的答案:
public interface IFooModel<out T>
where T : BaseBarModel
{
string Title { get; }
Table<T> Table { get; } // this causes an error:
// Invalid variance: The type parameter 'T' must be
// invariantly valid on IFooModel<T>.Table.
// 'T' is covariant.
}
public abstract class BaseFooModel<T> : IFooModel<T>
where T : BaseBarModel
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
结束了什么:
public interface IFooModel<out T>
where T : BaseBarModel
{
string Title { get; }
BaseModule Table { get; } // Table<T> inherits from BaseModule
// And I only need methods from BaseModule
// in my view.
}
public abstract class BaseFooModel<T> : IFooModel<T>
where T : BaseBarModel
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*ale 19
您需要在类层次结构中引入一个带有协变泛型类型参数的接口:
public interface IFooModel<out T> where T : BaseBarType
{
}
Run Code Online (Sandbox Code Playgroud)
并从上面的接口派生您的BaseFooModel.
public abstract class BaseFooModel<T> : IFooModel<T> where T : BaseBarType
{
}
Run Code Online (Sandbox Code Playgroud)
在你的控制器中:
[HttpGet]
public ActionResult Index()
{
return View(new MyFooModel());
}
Run Code Online (Sandbox Code Playgroud)
最后,将视图的模型参数更新为:
@model IFooModel<BaseBarType>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4211 次 |
| 最近记录: |