动态类型转换为内部类型的通用列表

时间:2013-05-23 21:44:15

标签: c# reflection casting

我正在使用第三方API,我需要访问内部字段(“_fieldOfA”)的私有字段(“_fieldOfB”)。下面的例子说明了这个组成。我正在寻找的字段是内部类型列表(ClassCClassD是内部类型并在同一个程序集中)。

 public abstract class ClassA
 {
    internal ClassB _fieldOfA;
 }

 public class ClassB
 {
    private readonly List<ClassC<ClassD, int>> _fieldOfB;
 }

我尝试过反射,但我似乎无法将最终类型转换为正确 - 动态类型保持Object(请注意我的类扩展ClassA

var assemblyHandle = typeof (ClassB).Assembly;
var genericTypeC = assemblyHandle.GetType("ApiNamespace.ClassC`2");
var typeD = assemblyHandle.GetType("ApiNamespace.ClassD");

var genericTypesForC = new Type[] { typeD, typeof(int) };
var typeC = genericTypeC.MakeGenericType(genericTypesForC);
var typeOfList = typeof(List<>).MakeGenericType(typeC);

var fieldOfAInfo= typeof(ClassA).GetField("_fieldOfA", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
var fieldOfAValue = fieldOfAInfo.GetValue(this);

var fieldOfBInfo= typeof(ClassB).GetField("_fieldOfB", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
var uncastedFieldOfBValue = fieldOfBInfo.GetValue(fieldOfAValue);

dynamic fieldOfBValue = Convert.ChangeType(uncastedFieldOfBValue, typeOfList);

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以执行的更轻松访问List<ClassC<ClassD, int>>中的项目(根据评论将对象投射到IList后)使用Enumerable.Cast<TResult>扩展方法在列表中为您提供dynamic个对象的枚举;这样,您可以简单地让运行时绑定您的调用,而不是使用反射。

IList nonGenericList = uncastedFieldOfBValue as IList;
IEnumerable<dynamic> dynamicEnumerable = nonGenericList.Cast<dynamic>();

foreach (dynamic obj in dynamicEnumerable)
{
    // work with your objects here
}

当然,这只允许您访问位于第三方程序集中的实例上的public方法和属性。如果您想使用内部版本,可以查看one of these个博客文章,了解如何创建允许您将调用绑定到非DynamicObject的{​​{1}}包装器 - 使用反射的公共成员。