//Parent class namespace 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 class namespace 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=nullMessage = newObj
AssemblyQualifiedName=Framework.DataModel.CADElementRequest,
Framework.DataModel,Culture=neutral,
PublicKeyToken=null,BaseType==Framework.DataModel.DataTreeRequest,
FullName==Framework.DataModel.CADElementRequestBaseException: 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中的“备注”部分