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

标签 c# .net

我有一个使用反射动态创建类的应用程序。部署后,将派生类转换为其基类时出现异常。它只发生在 100 台机器中的 1 台上。所有的类都在同一个程序集中。下面是一些代码片段和在强制转换异常之前的日志消息的输出。我束手无策,非常感谢任何帮助。

//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=null

Message = newObj AssemblyQualifiedName=Framework.DataModel.CADElementRequest, Framework.DataModel, Version=1.0.5885.31486, 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 中的备注部分

关于C# 通过反射将派生类转换为基类异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35381686/

相关文章:

c# - 为什么这不会产生幸运数字?

c# - 异步填充强类型数据集

.net - 服务类型优先于运营商代码;用于评估错误的服务类型

c# - 有没有办法告诉我在运行时使用的是哪个枚举?

c# - Linq any - 如何选择

c# - 尝试浏览信号器/集线器时 HTTP 503 服务不可用

c# - 案例陈述的更好替代方案

c# - List.Contains 对象比较失败

c# - 具有通用接口(interface)的通用方法

c# - 复选框列表选中的值