2016-02-13 18 views
12

Ich habe eine App, die Klassen dynamisch mit Reflektion erstellt. Bei der Bereitstellung wird eine Ausnahme ausgelöst, wenn eine abgeleitete Klasse in ihre Basisklasse umgewandelt wird. Es passiert nur bei 1 von 100 Maschinen. Alle Klassen befinden sich in derselben Baugruppe. Im Folgenden finden Sie einige Code-Snippets und die Ausgabe aus einer Protokollierungsnachricht unmittelbar vor der Ausnahme für das Casting. Ich bin am Ende meiner Weisheit, jede Hilfe sehr geschätzt.C# Cast abgeleitete Klasse zu Basisklasse Ausnahme über Reflexion

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

Logging Ausgabe auf ausgefallene Maschine:

Message = Gefunden Montag = 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: Kann newObj nicht umschreiben, um DataTreeRequest einzugeben. NEWOBJ = Name = Umspannwerke; InType =; inname = Umspannwerke; OutName = Umspannwerke; InSource =; Outsource = ;, Type = Framework.DataModel.CADElementRequest

+0

eine Behauptung hinzu 'newObj.GetType(). Baseclass == typeof (DataTreeRequest)'. Sollte Feuer machen. Fügen Sie außerdem die Protokollierung für die vollqualifizierten Typnamen hinzu. Gibt es möglicherweise mehrere Versionen derselben Baugruppe? Vielleicht ein Fehler bei der Bereitstellung? – usr

+0

Es ist bereits auf der Fehlermeldung "BaseType == Framework.DataModel.DataTreeRequest, " – CodeNotFound

+0

@CodeNotFound das ist nur der Typ Name, Assembly fehlt. – usr

Antwort

1

try

Assembly asm = Assembly.LoadFrom(asmName); 
if (asm == null) 
{ 
    throw new BaseException("Can't find assembly " + asmName); 
} 

Type requestType = asm.GetType(inType); 

zu ersetzen

Type requestType = Type.GetType(inType) 

wo Intype ist Montage qualifizierten Namen https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx

Wenn Sie eine Ladebaugruppe benötigen, die nicht vom Projekt referenziert wird, ziehen Sie die Assembly.Load-Methode in Betracht.

Über Nachteile Assembly.LoadFrom mit Leseabschnitt Bemerkungen in https://msdn.microsoft.com/EN-US/library/1009fa28(v=VS.110,d=hv.2).aspx

0

die rote Fahne ist es auf bestimmten Maschinen versagt (1 von 100) - wie viele Maschinen insgesamt wird der Code nicht auf? Dies deutet darauf hin, dass es sich eher um die Konfiguration der Maschine als um den Code handelt. Es macht es auch extrem schwierig zu replizieren, um zu helfen.

Wenn ich es wäre. Ich würde einen Schritt zurück machen und die Situation vereinfachen. Schreiben Sie Code, der nur die fehlgeschlagene Aufgabe ausführt, selbst mit anderen einfacheren Klassen, und konzentrieren Sie sich dann auf eine fehlerhafte Maschine. Holen Sie so viele Informationen wie möglich und bauen Sie Verständnis auf.

Es ist wahrscheinlich, referent Schmerzen. Die Situation, in der Sie sich befinden, ist nur ein Symptom für das eigentliche Problem. Sie konzentrieren sich auf den Code, aber das ist nur ein Symptom. Deshalb wäre es gut zu vereinfachen.

hoffte, das hilft, ich bin neu zu Stackoverflow und ich weiß, dass es Regeln für Fragen zu folgen. Ich hätte dies zu einem Kommentar gemacht, aber dafür habe ich keinen guten Ruf.

Verwandte Themen