我在 ASP.Net MVC 网站上工作,我一直坚持使用泛型让我的 C# 代码与我的 View 配合得很好。
我有一个将模型传递给 View 的 Controller (到目前为止还不错)。模型的类型为 IDescribedEnumerable<T>
对 T
有一些限制,其中有一个约束 T
继承自接口(interface) ( IDescribedModel
)。
我可以轻松编写一个接受 IDescribedEnumerable<Country>
的 View 只要 T
就会有效实际上是 Country
类型.
但是,我还想编写一个接受 IDescribedEnumerable
的默认 View 的 <<whatever>>
这将呈现它。这应该是完全可能的。我并不总是需要知道模型的具体类型。通常只知道它是 IDescribedModel
就够了。
只要我留在 C# 中,就没有问题。当我不关心具体类型时,我只是将方法和对象声明为接受 <T>
。 .当我关心时,我宣布他们接受 Country
.
但是:
(1) 如果我想呈现一个 View ,我必须选择一个类型。我不能只说 Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
我必须在 <>
之间指定现有类型. (即使我要从 ViewUserControl
继承,我也必须将其转换为 IDescribedEnumerable<<something>>
。
(2) 理想情况下,我会说模型是 IDescribedEnumerable<IDescribedModel>
在默认 View 和 IDescribedEnumerable<Country>
中在具体实现中。但是,然后我的 Controller 需要知道他是要渲染到默认 View 还是特定 View 。不可能简单地转换一个 IDescribedEnumerable<Country>
的对象。至 IDescribedEnumerable<IDescribedModel>
. (IIRC 在 C# 4 中是可能的,但我使用的是 3.5)
那我该怎么办呢?我能想到的所有选项都不是最佳选择(我不希望删除泛型并只是四处转换对象,也不希望复制粘贴默认 View 65 次并保持副本同步,也不希望进行反射并创建一个基于已知 Type
对象的对象)
最佳答案
在等待一些 C# 天才来回答我所有的问题时,我已经实现了 IEnumerable 也使用的技巧:
我添加了一个方法 public IDescribedEnumerable<IDescribedModel> AsIDescribedModels()
到 IDescribedEnumerable 接口(interface)并创建一个新类 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;
}
}
关于c# - 如何将通用对象传递给 Aspx 页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1899865/