2014-08-29 8 views
14

Exception Nachricht: Constructor on type StateLog not found.Konstruktor bei Typ nicht gefunden

Ich habe den folgenden Code, der nicht nur für eine Klasse nicht funktioniert:

 List<T> list = new List<T>(); 
     string line; 
     string[] lines; 

     HttpWebResponse resp = (HttpWebResponse)HttpWebRequest.Create(requestURL).GetResponse(); 

     using (var reader = new StreamReader(resp.GetResponseStream())) 
     { 
      while ((line = reader.ReadLine()) != null) 
      { 
       lines = line.Split(splitParams); 
       list.Add((T)Activator.CreateInstance(typeof(T), lines)); 
      } 
     } 

Der Konstruktor für die Klasse, die es nicht für wie die anderen Klassen ist genau das funktioniert, für die es funktioniert. Der einzige Unterschied besteht darin, dass dieser Klasse 16 Argumente statt 2-5 übergeben werden. Der Konstruktor sieht aus, als solche:

public StateLog(string[] line) 
    { 
     try 
     { 
      SessionID = long.Parse(line[0]); 
      AgentNumber = int.Parse(line[1]); 
      StateIndex = int.Parse(line[5]); 
      .... 
     } 
     catch (ArgumentNullException anex) 
     { 
      .... 
     } 
    } 

Wie ich schon sagte, ist es für die anderen fünf Klassen arbeitet, die diese verwenden, der einzige Unterschied ist die Anzahl der Eingänge.

+1

Auf eine ernstere Anmerkung sollten Sie vielleicht etwas Zeit investieren, um uns zu sagen, wie es nicht funktioniert. Fehlermeldungen? – spender

+0

Ist 'StateLog' Klasse aus diesem Bereich sichtbar? Hat es zusätzliche Konstruktorüberladungen? – Groo

+0

Ich dachte, die Fehlermeldung für den Titel der Frage würde ausreichen, um das Problem zu extrapolieren. Werde Dich auf dem Laufenden halten. – JRLambert

Antwort

32

Das liegt daran, dass Sie die Activator.CreateInstance overload verwenden, die ein Objektarray akzeptiert, das eine Liste von Konstruktorparametern enthalten soll. Mit anderen Worten, es wird versucht, eine StateLog Konstruktorüberladung zu finden, die 16 Parameter anstelle von einem hat. Dies ergibt sich aufgrund array covariance.

Also, wenn der Compiler diesen Ausdruck sieht:

Activator.CreateInstance(typeof(T), lines) 

seit lines ist ein string[], es setzt man auf Kovarianz verlassen wollen, dass es automatisch auf object[] geworfen zu haben, was bedeutet, dass der Compiler sieht es tatsächlich wie dies:

Activator.CreateInstance(typeof(T), (object[])lines) 

Das Verfahren wird dann versuchen, einen Konstruktor zu finden, das eine Anzahl von Parametern gleich lines.Length hat, alle vom Typ string.

Zum Beispiel, wenn Sie diese Erbauer:

class StateLog 
{ 
     public StateLog(string[] line) { ... } 
     public StateLog(string a, string b, string c) { ... } 
} 

Aufruf Activator.CreateInstance(typeof(StateLog), new string[] { "a", "b", "c" }) den zweiten Konstruktor (die mit drei Parametern) aufrufen, anstelle des ersten.

Was Sie wirklich wollen, ist die gesamte lines Array als erstes Array-Element passieren, effektiv:

var parameters = new object[1]; 
parameters[0] = lines; 
Activator.CreateInstance(typeof(T), parameters) 

Natürlich können Sie einfach eine Inline-Feldinitialisierung verwenden:

list.Add((T)Activator.CreateInstance(typeof(T), new object[] { lines })); 
+0

Wie funktioniert es dann für meine anderen Klassen, die 'string []' als Konstruktorparameter akzeptieren? – JRLambert

+0

Haben diese Klassen unterschiedliche ctor-Überlastungen, die mehr Parameter akzeptieren? Es gibt nicht viel, die Methode sucht einfach nach einem passenden Konstruktor (wobei die Anzahl der Parameter und deren Typen übereinstimmen muss). – Groo

+0

Ja, aber das tut es auch. – JRLambert

Verwandte Themen