2

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

 public abstract class ClassA
 {
    internal ClassB _fieldOfA;
 }

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

我已经尝试过反射,但我似乎无法正确转换最终类型 - 动态类型保持不变Object(请注意我的类 extends 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);

有任何想法吗?

4

1 回答 1

2

您可以更轻松地访问 中的项目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位于第三方程序集中的实例上的方法和属性。如果您想使用内部结构,可以查看其中 一篇博客文章,了解如何创建一个包装器,允许您使用反射将调用绑定到非公共成员。 DynamicObject

于 2013-05-24T16:18:04.327 回答