我写的扩展如下:
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, bool> predicate) where T : class, new()
{
....
}
下面显示的类Sample是使用Reflection TypeBuilder动态创建的。 我创建运行时的对象实例就像:
public class Sample
{
public Sample()
{
Children= new ObservableTestCollection<Sample>(this);
}
public Sample(IEnumerable<Sample> source)
{
Children= new ObservableTestCollection<Sample>(this, source);
}
public ObservableTestCollection<Sample> Children;
}
上面的ObservableTestCollection由ObservableCollection
派生 下面的typeBuilder是由Reflection TypeBuilder构建的。 我喜欢做的是:
var type = typeBuilder.CreateType();
var obj = Activator.CreateInstance(type);
var results = (IEnumerable<...>)(obj.GetProperty("Children").GetValue(obj)).Traverse(s=>s!=null);
这里的问题是我无法转换为IEnumerable,因为Sample for Sample是由反射TypeBuilder创建的。这意味着代码中的Sample没有明确的类型。
所以,我想找出一些方法来转换泛型IEnumerable<...>
或调用Traverse的扩展方法。
提前致谢。
答案 0 :(得分:2)
您的ObservableTestCollection<T>
必须实现类型IEnumerable<T>
,或者从具有该实现的类型派生才能使用您的扩展方法,如下所示:
public class ObservableTestCollection<T> : IEnumerable<T>
{
private Sample sample;
private IEnumerable<Sample> source;
public ObservableTestCollection(Sample sample)
{
this.sample = sample;
}
public ObservableTestCollection(Sample sample, IEnumerable<Sample> source)
{
this.sample = sample;
this.source = source;
}
public IEnumerator<T> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
然后你可以像这样反思:
var obj = Activator.CreateInstance(typeof(Sample));
var pi = obj.GetType().GetProperty("Children");
var ct = Convert.ChangeType(obj, pi.PropertyType) as ObservableTestCollection<Sample>;
var results = (IEnumerable <Sample>)(ct as IEnumerable<object>).Traverse(s => s.Equals("1"));
我正在object
使用T
但您可以使用您需要的任何内容。此外,您需要在运行时向Children
属性添加一些项目,以便您可以使用扩展程序遍历它们 - 但我认为您知道这一点。
修改强>
您修改了问题并添加了此内容:
这里的问题是我无法转换为IEnumerable,因为Sample for Sample是由反射TypeBuilder创建的。这意味着代码中的Sample没有明确的类型。
无关紧要,它仍然有效。这里有一些代码,我甚至没有提到Sample
作为类,而是作为动态创建的类型:
AssemblyName assemblyName
= new AssemblyName("MyDynamicAssembly");
AssemblyBuilder assemblyBuilder
= AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder
= assemblyBuilder.DefineDynamicModule("MyDynamicModule");
TypeBuilder typeBuilder
= moduleBuilder.DefineType("Sample");
var obj = Activator.CreateInstance(typeBuilder.CreateType());
var pi = obj.GetType().GetProperty("Children");
var ct = Convert.ChangeType(obj, pi.PropertyType) as IEnumerable<object>;
var results = (ct as IEnumerable<object>).Traverse(s => s.Equals("1"));