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>>オブジェクトを にキャストした後)の項目により簡単にアクセスするためにできることは、リストで拡張メソッドを使用して、オブジェクトの列挙を提供することです。この方法では、リフレクションを使用する代わりに、ランタイムに呼び出しをバインドさせるだけです。IListEnumerable.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 に答える