如果直到运行时才知道T,我如何将IEnumerable
转换为IEnumerable<T>
?
我有一个绝对需要IEnumerable<T>
的方法,其中T在运行之前是未知的, T
必须是实际类型而不是祖先类型喜欢对象。
我认为反射API允许这样的东西,但我不确切知道如何。
我可以得到这样的类型对象:
var first = results.Cast<object>().FirstOrDefault();
if (first != null)
{
var type = first.GetType();
}
我所指的“方法”实际上是WPF DataGrid的ItemSource属性的Setter。
我遇到的问题是,如果我没有传递IEnumerable<T>
数据网格中生成的行都是空白的,就好像它反映T
属性的方法不起作用,它无法生成列。
即使使用此代码也会产生这种不良影响:
public CollectionResultWindow(IEnumerable results)
{
Contract.Requires(results != null, "results is null.");
InitializeComponent();
DataContext = this;
var first = results.Cast<object>().FirstOrDefault();
if (first != null)
{
Type type = first.GetType();
var castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(type);
dynamic genericResults = castMethod.Invoke(null, new[] { results });
Results = genericResults; // Results is a dependency property that DataGrid.ItemSource is bound to.
}
}
答案 0 :(得分:7)
var elementType = ...
var results = ...
var castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(elementType);
var genericResults = castMethod.Invoke(null, new[] { results });
genericResults
变量引用IEnumerable<T>
类型的对象(其中T
是elementType
变量所代表的类型)。但请注意,静态genericResults
仍为object
类型;没有办法告诉编译器它是IEnumerable<T>
,因为T
不是静态知道的。
答案 1 :(得分:0)
以下代码对我有用:
public CollectionResultWindow(IEnumerable results)
{
Contract.Requires(results != null, "results is null.");
InitializeComponent();
DataContext = this;
var first = results.Cast<object>().FirstOrDefault();
if (first != null)
{
Type type = first.GetType();
var castMethod = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(type);
dynamic genericResults = castMethod.Invoke(null, new[] { results });
Results = genericResults; // Results is a dependency property that DataGrid.ItemSource is bound to.
}
}