我已经为一个自定义泛型类(TabularList<>
)创建了一个通用JavaScriptConverter
派生,我已将其命名为ITabularConverter<>
。 ITabularConverter
使用反射来检索从TabularList<>
泛型类型定义派生的所有封闭类型,以通知JavaScriptSerializer它能够转换所有闭合类型ITabularConverter<>
。该代码看起来是这样的:为什么封闭泛型不能由Assembly.GetTypes()返回?
public override IEnumerable<Type> SupportedTypes
{
get
{
var type = typeof (TabularList<>);
var itabulars = Assembly.GetAssembly(type).GetTypes()
.Where(t => t.IsGenericType
&& t.GetGenericTypeDefinition() == type);
return itabulars;
}
}
的问题是,即使有这个代码执行的时间存在至少一个封闭式TabularList <>的,只有开放式泛型类型定义是由上述返回码。当我将搜索扩展到所有当前加载的程序集时也是如此。
更奇怪的是,如果我检查调用堆栈,我可以看到JavaScriptSerializer.Serialize方法被调用的位置,并使用立即窗口检查被序列化的对象并证明存在通用定义的封闭版本。然而,当我在立即窗口执行下面的代码,结果是false
:
Assembly.GetAssembly(obj.TabularListProp.GetType())
.GetTypes()
.Contains(obj.TabularListProp.GetType());
所以我找回其中封闭的通用定义,然后寻找通过定义的类型中,封闭式泛型类型的程序集该组件,并找不到封闭类型。这有什么意义呢?
这里是TabularList<>
声明:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
namespace Central.Claims.UX.ClaimWFMgrViewModel
{
[Serializable]
public class TabularList<T> : List<T>, ITabular
{
private List<List<object>> _tableView;
[XmlIgnore]
public List<List<object>> TableView
{
get { return GetTableView(); }
}
private List<KeyValuePair<string, Func<object, object>>> Schema { get; set; }
public TabularList()
{
Initialize();
}
public TabularList(IEnumerable<T> source) : base(source)
{
Initialize();
}
private void Initialize()
{
RefreshTableView = true;
var type = typeof(T);
if (Schemas.ContainsKey(type.Name))
{
Schema = Schemas[type.Name];
}
else
{
Schema = new List<KeyValuePair<string, Func<object, object>>>();
}
}
protected List<List<object>> GetTableView()
{
GetSchema();
BuildTable();
return _tableView;
}
private void GetSchema()
{
if (this.Any())
{
var properties = this.First().GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var property in properties)
{
var getter = property.GetGetMethod();
Schema.Add(new KeyValuePair<string, Func<object, object>>(
property.Name,
(Func<object, object>) Delegate.CreateDelegate(typeof (Func<object, object>), getter)
));
}
}
}
private void BuildTable()
{
_tableView = new List<List<object>>();
foreach (var item in this)
{
TableView.Add(ToTableRow(item));
}
}
private List<object> ToTableRow(T item)
{
var row = new List<object>();
foreach (var column in Schema)
{
row.Add(column.Value(item));
}
return row;
}
}
}
基于这里提供的答案,我已经改写在这个问题上的SO质疑How to retrieve a list of all closed generic types generated by the .NET runtime?
是否型,其中'TabularList <>'类型是相同的组件存在:您可以通过在类型的主叫
GetGenericTypeDefinition()
得到泛型类型定义? – DavidG发布您的类声明,并确定'GetTypes'不会返回它吗?或者你的where条件过滤它?对于不带任何类型参数的类型,IsGenericType将为false。 –
@DavidG - 不,类型是在同一解决方案的另一个项目中定义的,而这些代码片段位于Web应用程序中。 –