私は、他のC#実行可能ファイルを調べ、単体テストを介して、それらが公開するインターフェイスに関する特定のプロパティをアサートすることになっているC#アプリケーションに取り組んでいます。(コンテキストとして、これはCSコースの評価アプリケーションです。割り当ては、テキストファイルから数値範囲を解析し、固定インターフェイスに従ってそれらを返すことです。)
これまでのところ、私は次のことに成功しました。
assembly
を使用して、実行可能ファイルを変数としてロードしますAssembly.LoadFrom(string)
- を使用して、問題のインターフェイスのタイプを取得します
assembly.GetType(string)
- インターフェースの実装タイプを見つけます。
assembly.getType(string)
- およびを使用して、実装タイプを
dynamic
オブジェクトにインスタンス化します。type.GetConstructor(Type[])
constructor.Invoke(Object[])
この時点で、テストしているインターフェイスを実装していることがわかっているdynamic
オブジェクトがあります。loader
のインターフェイスメソッドの1つを呼び出したいobj
ので、次を実行します。
dynamic rangeSet = loader.GetRangeSetFromFile (inputFile); // inputFile is a string
InvalidCastException
これにより、次のトレースがスローされます。
System.InvalidCastException : Cannot cast from source type to destination type.
at SwapAssignment3.Implementations.RangeLoaderAdapter.GetRangeSetFromFile (string) <IL 0x0001e, 0x00066>
at (wrapper dynamic-method) object.CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object,string) <IL 0x00036, 0x0007b>
at System.Dynamic.UpdateDelegates.UpdateAndExecute2<object, string, object> (System.Runtime.CompilerServices.CallSite,object,string) <0x003cf>
at AssignmentTests.R3Test.TestLoadingViaInterface () [0x00054] in /Users/tim/Dropbox/Courses/CSSE375-TA/AssignmentTests/AssignmentTests/R3Test.cs:82
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <0x00003>
at System.Reflection.MonoMethod.Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <IL 0x000db, 0x00147>
なぜこのエラーがスローされるのでしょうか?問題の実行可能ファイルを実行することは、それ自体で問題なく機能します。このエラーは、私のテストアプリケーションのコンテキストでのみスローされます。メソッドの本体は次のGetRangeSetFromFile
とおりです。
public IRangeSet GetRangeSetFromFile(string filePath)
{
var newRange = new RangeStorage();
_fileProcessor.ProcessFile(filePath);
newRange.StoreElements((List<IRange>) _fileProcessor.GetStorage());
return newRange;
}
私は(とりわけプログラム出力から)キャストエラーがキャストとともに3行目から発生していると信じる十分な理由がありList<IRange>
ます。ただし、トレースはILの場所を示しているため、これを100%確信しているわけではなく、プログラムが単独で実行されている場合は正常に機能するため、そもそもなぜそのキャストが失敗するのかわかりません(テスター)。
私の主な質問は、なぜこのキャストエラーが発生するのか、そしてどうすればそれを回避できるのかということです。
編集:リクエストにより、テストコードは次のようになります。
Type interfaceType = assembly.GetType("IRangeLoader");
List<Type> implementingTypes = new List<Type> (assembly.GetTypes ())
.FindAll ((Type t) => t.IsClass)
.FindAll ((Type t) => (new List<Type> (t.GetInterfaces ())).Contains (interfaceType));
Type implementingType = implementingTypes[0];
ConstructorInfo ctor = implementationType.GetConstructor (new Type[] {});
dynamic loader = ctor.Invoke (new Object[] {});
dynamic rangeSet = loader.GetRangeSetFromFile ("sample range.txt");