簡體   English   中英

C#通過反射將派生類轉換為基類異常

[英]C# cast derived class to base class exception via reflection

我有一個使用反射動態創建類的應用程序。 部署時,在將派生類強制轉換為基類時會出現異常。 它只發生在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:無法將newObj強制轉換為類型DataTreeRequest。 newObj = Name = Subations; 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中的備注部分

紅旗是否在特定機器上失敗(100個中的1個) - 代碼總共有多少台機器失敗? 這表明它可能是機器的配置而不是代碼。 它也使復制起來非常困難以幫助。

如果是我。 我退后一步,簡化情況。 編寫只執行失敗任務的代碼,即使是其他更簡單的類,然后專注於失敗的機器。 獲取盡可能多的信息並建立理解。

這可能是指稱痛苦。 你面臨的情況只是真正問題的症狀。 你專注於代碼,但這只是一個症狀。 這就是為什么簡化會很好的原因。

希望這會有所幫助,我是stackoverflow的新手,我知道有一些規則要遵循問題。 我已經發表了評論,但我沒有這個名聲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM