Reputation: 51
I am using a third party API and I need to access a private field ("_fieldOfB") of an internal field ("_fieldOfA"). The example below illustrates the composition. The field I am looking for is a List of internal types (ClassC
and ClassD
are internal and in the same assembly).
public abstract class ClassA
{
internal ClassB _fieldOfA;
}
public class ClassB
{
private readonly List<ClassC<ClassD, int>> _fieldOfB;
}
I have tried with reflection, but I can't seem to get the final type cast right - the dynamic type stays Object
(note that my class 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);
Any ideas?
Upvotes: 2
Views: 1629
Reputation: 26883
Something you can do to more easily access the items in the List<ClassC<ClassD, int>>
(after you've cast the object to IList
, per the comments) is to use the Enumerable.Cast<TResult>
extension method on your list to provide you with an enumeration of dynamic
objects; this way, instead of using reflection, you can simply have the runtime bind your calls for you.
IList nonGenericList = uncastedFieldOfBValue as IList;
IEnumerable<dynamic> dynamicEnumerable = nonGenericList.Cast<dynamic>();
foreach (dynamic obj in dynamicEnumerable)
{
// work with your objects here
}
Of course, this will only allow you to access public
methods and properties on instances located in the third-party assembly. If you want to play with the internals, you can look at one of these blog posts to see how to create a DynamicObject
wrapper that allows you to bind calls to non-public members using reflection.
Upvotes: 2