gpt4 book ai didi

C#:反射实例化对象抛出转换错误?

转载 作者:太空宇宙 更新时间:2023-11-03 11:22:40 25 4
gpt4 key购买 nike

我正在开发一个 C# 应用程序,它应该检查其他 C# 可执行文件并通过单元测试断言它们公开的接口(interface)的某些属性。 (对于上下文,这是一个 CS 类(class)的评分应用程序;作业是从文本文件中解析数字范围并根据固定接口(interface)返回它们。)

到目前为止,我已经设法:

  • 加载可执行文件作为变量assembly , 使用 Assembly.LoadFrom(string)
  • 获取相关接口(interface)的类型,使用 assembly.GetType(string)
  • 再次使用assembly.getType(string) 找到接口(interface)的实现类型
  • 将实现类型实例化为 dynamic对象,使用 type.GetConstructor(Type[])constructor.Invoke(Object[])

此时,我有一个 dynamic对象 loader我知道实现我正在测试的接口(interface)。我想在 obj 上调用接口(interface)方法之一,所以我运行:

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;
}

我有充分的理由相信(从程序输出,除其他外)转换错误是从第三行引发的,带有 List<IRange> throw ;然而,由于跟踪给出了 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");

最佳答案

好的,下面的代码似乎可以在另一个程序集中调用该方法:

Assembly testAssembly = Assembly.LoadFile(<path>);

var interfaceType = testAssembly.GetTypes().Where(x => x.Name == "ISampleInterface").FirstOrDefault();

if(interfaceType != null)
{
var implementingType = testAssembly.GetTypes().Where(typ => type.GetInterfaces().Any(iface => iface == interfaceType)).FirstOrDefault();

if(implementingType != null)
{
dynamic obj = Activator.CreateInstance(implementingType);

dynamic result = obj.SampleInterfaceMethod();

Console.WriteLine(result);
}
}

尝试使用其中的一些。我能够调用该对象,然后从该方法返回结果。

关于C#:反射实例化对象抛出转换错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10436274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com