C# · 12月 27, 2021

C#通过反射将派生类转换为基类异常

我有一个应用程序使用反射动态创建类.部署时,将派生类转换为基类时会得到异常.它只发生在100台机器中.所有的类都在同一个程序集中.以下是一些代码片段,并且在发生异常之前的日志消息中输出.我在我的智慧结局,任何帮助非常感谢. //Parent classnamespace Framework.DataModel{ [Serializable] public class DataTreeRequest : TreeNode,IDirtyListener,ISerializable { …. }}// Derived Class namespace Framework.DataModel{ [Serializable] public class CADElementRequest : DataTreeRequest { public CADElementRequest(String name) : base(name){} }}// Method that uses reflection to create class and then cast to its base classnamespace Framework.DataModel{ [Serializable] public class DataModelBuilder : CoreBuilder { … protected DataTreeRequest CreateDataTreeRequest(String asmName,String inName,String inType,String inSourceName) { DataTreeRequest dtr = null; Assembly asm = Assembly.LoadFrom(asmName); if (asm == null) { throw new BaseException(“Can’t find assembly ” + asmName); } Type requestType = asm.GetType(inType); if (requestType == null) { throw new BaseException(“Can’t find class of type ” + inType + ” in assembly ” + asmName); } // Call the constructor for the tree node that takes the xml node as an argument Type[] constructorArgsTypes = new Type[1]; constructorArgsTypes[0] = typeof(String); ConstructorInfo constructorInfo = requestType.GetConstructor(constructorArgsTypes); if (constructorInfo == null) { throw new BaseException(“Can’t find constructor for type ” + inType + ” that takes a String param”); } Object[] constructorArgs = new Object[1]; constructorArgs[0] = inName; Object newObj = constructorInfo.Invoke(constructorArgs); // Code fails on this line trying to cast derived class to base class on 1 in 100 machines dtr = newObj as DataTreeRequest; if (dtr == null) { throw new BaseException(“Can’t cast newObj to type DataTreeRequest. newObj = ” + newObj + “,Type = ” + newObj.GetType().ToString()); } dtr.InSource = inSourceName; return dtr; } }}

在失败的机器上记录输出:

Message = Found assembly=Framework.DataModel,Version=1.0.5885.31486,
Culture=neutral,PublicKeyToken=null

Message = newObj
AssemblyQualifiedName=Framework.DataModel.CADElementRequest,
Framework.DataModel,Culture=neutral,
PublicKeyToken=null,BaseType==Framework.DataModel.DataTreeRequest,
FullName==Framework.DataModel.CADElementRequest

BaseException: Can’t cast newObj to type DataTreeRequest. newObj =
Name=Substations;InType=;InName=Substations;OutName=Substations;InSource=;OutSource=;,
Type = Framework.DataModel.CADElementRequest

解决方法 尝试更换 Assembly asm = Assembly.LoadFrom(asmName);if (asm == null){ throw new BaseException(“Can’t find assembly ” + asmName);}Type requestType = asm.GetType(inType);

Type requestType = Type.GetType(inType)

其中inType是程序集合的名称
https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx

如果您需要项目未引用的加载程序集考虑使用Assembly.Load方法.

关于使用Assembly.LoadFrom的缺点,请参阅https://msdn.microsoft.com/EN-US/library/1009fa28(v=VS.110,d=hv.2).aspx中的“备注”部分