我正在开发一个ASP.Net MVC网站,我一直在使用泛型来获取我的C#代码,以便与我的观点保持良好关系。
我有一个将模型传递给视图的控制器(到目前为止一直很好)。模型的类型为IDescribedEnumerable<T>
,对T
有一些约束,其中T
是从接口(IDescribedModel
)继承的约束。
我可以轻松编写一个接受IDescribedEnumerable<Country>
的视图,只要T
实际上是Country
类型,该视图就会有效。
但是,我还想编写一个默认视图,该视图接受IDescribedEnumerable
<<whatever>>
并将呈现它。这应该是完全可能的。我并不总是需要知道模型的具体类型。通常只知道它是IDescribedModel
就足够了。
只要我留在C#就没问题了。当我不关心特定类型时,我只是将方法和对象声明为接受<T>
。当我照顾时,我声明他们接受Country
。
但:
(1)如果我想渲染一个视图我必须选择一个类型。我不能只说Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
我必须在<>
之间指定现有类型。 (即使我要继承ViewUserControl
,我也必须将其投放到IDescribedEnumerable<<something>>
。
(2)理想情况下,我会说默认视图中的模型为IDescribedEnumerable<IDescribedModel>
,具体实现中为IDescribedEnumerable<Country>
。但是,我的Controller需要知道他是否要渲染到默认视图或特定视图。无法简单地将IDescribedEnumerable<Country>
的对象强制转换为IDescribedEnumerable<IDescribedModel>
。 (IIRC可以在C#4中使用,但我使用的是3.5)
那我该怎么办?我能想到的所有选项都是非常不理想的(我不期待删除泛型,只是将对象转换为周围,也不是复制粘贴默认视图65次并保持副本同步,也不会反射出色并创建一个对象基于已知的Type
对象)
答案 0 :(得分:0)
我在IDescribedEnumerable接口中添加了一个方法public IDescribedEnumerable<IDescribedModel> AsIDescribedModels()
,并创建了一个新类GenericDescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel>
。在我的DescribedEnumerable<T>
类中,我创建了一个GenericDescribedEnumerable并返回它。在GenericDescribedEnumerable中,我返回this
完整代码:
public interface IDescribedModel<T> : IDescribedModel{
T original {
get;
}
}
public interface IDescribedEnumerable {
IDescribedEnumerable<IViewModel> AsIViewModels();
}
public interface IDescribedEnumerable<T> : IDescribedEnumerable
where T : IDescribedModel{
IEnumerable<T> GetViewModels();
}
public class DescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel<T>>{
public DescribedEnumerable(IEnumerable<T> enumerable) {}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return new GenericDescribedEnumerable<T>(/*allProperties*/);
}
public IEnumerable<T> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new DescribedModel<T>( obj);
yield return vm;
}
}
}
public class GenericDescribedEnumerable<T> : IDescribedEnumerable<IViewModel>{
//pass in the constructor everything you need, or create in the
//constructor of DescribedEnumerable<T>
public GenericDescribedEnumerable(/*allProperties*/) {
}
public IEnumerable<IViewModel> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new PlatoViewModel<T>( obj );
yield return vm;
}
}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return this;
}
}
答案 1 :(得分:0)
是的,这将起作用或使用模型作为对象,并适当地投射它。这是ViewPage类使用的方法,使用ViewPage和ViewPage:ViewPage。
答案 2 :(得分:0)
Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
...
Model.Cast<IModel>()