我开发了一个用于生成显示和可编辑表的 MVC 助手(需要一个 jquery 插件来允许在可编辑表中动态添加和删除具有完整回发的行),例如
@Htm.TableDisplayFor(m => m.MyCollection as ICollection)
与属性一起使用将包括页脚中的总计,为查看和编辑链接添加列,为复杂类型呈现超链接等。例如
[TableColumn(IncludeTotals = true)]
我即将在 CodeProject 上发布它,但在此之前,我想解决一个问题。助手首先ModelMetadata
从表达式中获取,检查它是否实现ICollection
,然后获取集合中的类型(注意以下片段来自 SO 上接受的答案,但如下所述,并不完全正确)
if (collection.GetType().IsGenericType)
{
Type type = collection.GetType().GetGenericArguments()[0]
该类型用于生成ModelMetadata
表头(表中可能没有任何行)和表体中的每一行(以防某些项目是具有附加属性的继承类型,否则会搞砸列布局)
foreach (var item in collection)
{
ModelMetadata itemMetadata = ModelMetadataProviders.Current
.GetMetadataForType(() => item, type);
我希望能够做的是使用而IEnumerable
不是不需要在 linq 表达式上调用它。ICollection
.ToList()
在大多数情况下IEnumerable
工作正常,例如
IEnumerable items = MyCollection.Where(i => i....);
可以,因为.GetGenericArguments()
返回一个仅包含一种类型的数组。问题是某些查询上的 '.GetGenericArguments()' 返回 2 种或更多类型,并且似乎没有逻辑顺序。例如
IEnumerable items = MyCollection.OrderBy(i => i...);
返回 [0] 集合中的类型,以及 [1] 用于排序的类型。
在这种情况下.GetGenericArguments()[0]
仍然有效,但是
MyCollection.Select(i => new AnotherItem()
{
ID = i.ID,
Name = 1.Name
}
返回 [0] 原始集合中的类型和 [1] 的类型AnotherItem
所以.GetGenericArguments()[1]
我需要为AnotherItem
.
我的问题是,有没有一种可靠的方法使用条件语句来获取我需要呈现表格的类型?
到目前为止,从我的测试来看,除了因为排序键是最后一种类型,使用.GetGenericArguments().Last()
在所有情况下都有效。OrderBy()
到目前为止,我尝试过的一些事情包括忽略作为值类型的类型(通常是这种情况OrderBy()
,但OrderBy()
查询可能使用 a string
(可以检查)或更糟糕的是,重载 ==、< 和 > 的类运算符(在这种情况下,我将无法判断哪个是正确的类型),并且我一直无法找到一种方法来测试集合是否实现了IOrderedEnumerable
.