novedades new features espaƱol c# constructor constructor-exception

c# - new - Constructor en tipo no encontrado



features c# (1)

Mensaje de excepción: Constructor on type StateLog not found .

Tengo el siguiente código que no funciona para una sola clase:

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

El constructor de la clase para la que no funciona es exactamente igual a las otras clases para las que trabaja. La única diferencia es que a esta clase se le pasarán 16 argumentos en lugar de 2-5. El constructor se ve como tal:

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

Como dije, funciona para las otras 5 clases que usan esto, la única diferencia es el número de entradas.


Esto se debe a que está utilizando la sobrecarga Activator.CreateInstance que acepta una matriz de objetos, que se supone que contiene una lista de parámetros del constructor. En otras palabras, está tratando de encontrar una sobrecarga del constructor de StateLog que tiene 16 parámetros, en lugar de uno. Esto se compila debido a la covarianza del array .

Entonces cuando el compilador ve esta expresión:

Activator.CreateInstance(typeof(T), lines)

Ya que las lines son una string[] , se supone que quieres confiar en la covarianza para que se convierta en object[] automáticamente, lo que significa que el compilador realmente lo ve así:

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

El método luego intentará encontrar un constructor que tenga una cantidad de parámetros igual a lines.Length . lines.Length , todos de tipo string .

Por ejemplo, si tienes estos constructores:

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

Al llamar a Activator.CreateInstance(typeof(StateLog), new string[] { "a", "b", "c" }) se llamará al segundo constructor (el que tiene tres parámetros), en lugar del primero.

Lo que realmente desea es pasar la matriz de lines completa como el primer elemento de la matriz , efectivamente:

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

Por supuesto, simplemente puede usar un inicializador de matriz en línea:

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