我正在使用第三方API,我需要访问内部字段(“_fieldOfA”)的私有字段(“_fieldOfB”)。下面的例子说明了这个组成。我正在寻找的字段是内部类型列表(ClassC
和ClassD
是内部类型并在同一个程序集中)。
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);
有什么想法吗?
答案 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}}包装器 - 使用反射的公共成员。