大图:
我发现了 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;
}
}
}
还有一个像这样的子类:
public class MyFooModel : BaseFooModel<MyBarType>
{
// ...
}
public class MyBarType : BaseBarType
{
// ...
}
我希望能够通过
MyFooModel
进入一个定义如下的 Razor View :// FooView.cshtml
@model BaseFooModel<BaseBarType>
但是,这是行不通的。我收到一个运行时错误,说
FooView
预计 BaseFooModel<BaseBarType>
但得到 MyFooModel
.回想一下 MyFooModel
来自 BaseFooModel<MyBarType>
的遗产和 MyBarType
继承自 BaseBarType
.我试过的:
我在非 Razor 的土地上尝试过这个,看看是否也是如此,它是。我必须在 View 中使用模板参数才能使其工作。这是非 Razor View :
public class FooView<T>
where T : BaseBarType
{
BaseFooModel<T> Model;
public FooView(BaseFooModel<T> model)
{
Model = model;
}
}
使用该结构,以下 确实有效 :
new FooView<MyBarType>(new MyFooModel());
我的问题:
我怎么能用 Razor 做到这一点? 如何像使用
FooView
一样传递类型?我不能 ,但是有没有办法解决这个问题?我能以某种方式实现相同的架构吗?
让我知道我是否可以提供更多信息。我正在使用 .NET 4 和 MVC 3。
编辑:
现在,我只是为
BaseFooModel<BaseBarType>
的每个子类添加一个 Razor View 。 .我对此并不感到兴奋,因为我不想每次添加新模型时都必须创建新 View 。另一种选择是利用这样一个事实,即我能够在没有 Razor 的情况下在常规 c# 类中使用它。我可以有我的 Razor View
@inherits
c# View ,然后调用一些渲染方法。我不喜欢这个选项,因为我不喜欢有两种呈现 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
{
// ...
}
最终的工作:
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
{
// ...
}
最佳答案
您需要引入一个带有 covariant 的接口(interface)泛型类型参数到您的类层次结构中:
public interface IFooModel<out T> where T : BaseBarType
{
}
并从上述接口(interface)派生您的 BaseFooModel 。
public abstract class BaseFooModel<T> : IFooModel<T> where T : BaseBarType
{
}
在您的 Controller 中:
[HttpGet]
public ActionResult Index()
{
return View(new MyFooModel());
}
最后,将 View 的模型参数更新为:
@model IFooModel<BaseBarType>
关于asp.net - 将通用模型的子类传递给 Razor View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15646812/