2014-08-29 45 views
14

Wiadomość wyjątku: Constructor on type StateLog not found.Konstruktor nie został znaleziony typ

Mam następujący kod, który nie działa na tylko jednej klasy:

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

Konstruktor klasy, że nie działa to dokładnie tak samo jak do innych klas, dla których to działa. Jedyna różnica polega na tym, że klasa ta otrzyma 16 argumentów zamiast 2-5. Konstruktor wygląda w następujący sposób:

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

Tak jak mówiłem, że pracuje dla pozostałych 5 klas, które korzystają z tego, jedyną różnicą jest ilość wejść.

+1

Co ważniejsze, być może warto poświęcić trochę czasu na powiedzenie nam, jak to nie działa. Komunikaty o błędach? – spender

+0

Czy klasa "StateLog' jest widoczna z tego zakresu? Czy ma dodatkowe przeciążenia konstruktora? – Groo

+0

Doszedłem do wniosku, że komunikat o błędzie w tytule pytania wystarczy do ekstrapolacji problemu. Zaktualizuję. – JRLambert

Odpowiedz

32

To dlatego, że używasz Activator.CreateInstance overload, która akceptuje tablicę obiektów, która powinna zawierać listę parametrów konstruktora. Innymi słowy, próbuje znaleźć przeciążenie konstruktora StateLog, które ma 16 parametrów zamiast jednego. Kompiluje się ze względu na array covariance.

Więc gdy kompilator widzi to wyrażenie:

Activator.CreateInstance(typeof(T), lines) 

od lines jest string[], przypuszcza chcesz polegać na kowariancji mieć automatycznie oddanych do object[], co oznacza, że ​​kompilator faktycznie widzi go jak to:

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

Sposób następnie spróbować znaleźć konstruktora, który ma szereg parametrów równych lines.Length, wszystkie typu string.

Na przykład, jeśli masz te konstruktorów:

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

Wywołanie Activator.CreateInstance(typeof(StateLog), new string[] { "a", "b", "c" }) zadzwoni drugi konstruktor (jednej z trzech parametrów), zamiast pierwszego.

co rzeczywiście chce to przekazać całą lines tablicę jako pierwszy element tablicy, skutecznie:

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

Oczywiście, można po prostu użyć inicjator tablicy inline:

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

Więc jak to działa dla moich innych klas, które akceptują 'string []' jako parametr konstruktora? – JRLambert

+0

Czy te klasy mają różne przeciążenia ctor, które akceptują więcej parametrów? Nie ma za bardzo wiele, metoda po prostu szuka odpowiedniego konstruktora (gdzie liczba parametrów i ich typy muszą się zgadzać). – Groo

+0

Tak, ale robi to samo. – JRLambert

Powiązane problemy