例外メッセージ:Constructor on type StateLog not found
。
私は次のコードを持っていますが、それは1つのクラスだけでは機能しません:
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));
}
}
動作しないクラスのコンストラクターは、動作する他のクラスとまったく同じです。唯一の違いは、このクラスに2〜5ではなく16個の引数が渡されることです。コンストラクターは次のようになります。
public StateLog(string[] line)
{
try
{
SessionID = long.Parse(line[0]);
AgentNumber = int.Parse(line[1]);
StateIndex = int.Parse(line[5]);
....
}
catch (ArgumentNullException anex)
{
....
}
}
私が言ったように、これを使用する他の5つのクラスで機能しますが、唯一の違いは入力数です。
これは、コンストラクタパラメータのリストを含むことになっているオブジェクト配列を受け入れる _Activator.CreateInstance
_オーバーロード を使用しているためです。つまり、1つではなく16個のパラメーターを持つStateLog
コンストラクターオーバーロードを見つけようとしています。これは array covariance によりコンパイルされます。
そのため、コンパイラが次の式を見たとき:
_Activator.CreateInstance(typeof(T), lines)
_
lines
は_string[]
_であるため、共分散に依存して_object[]
_に自動的にキャストすることを前提としているため、コンパイラは実際に次のように認識します。
_Activator.CreateInstance(typeof(T), (object[])lines)
_
次に、このメソッドは、すべてのタイプがstring
である_lines.Length
_に等しいパラメーターの数を持つコンストラクターを見つけようとします。
たとえば、これらのコンストラクターがある場合:
_class StateLog
{
public StateLog(string[] line) { ... }
public StateLog(string a, string b, string c) { ... }
}
_
Activator.CreateInstance(typeof(StateLog), new string[] { "a", "b", "c" })
を呼び出すと、最初のコンストラクターではなく、2番目のコンストラクター(3つのパラメーターを持つコンストラクター)が呼び出されます。
実際に必要なのは、entire lines
配列全体を最初の配列項目として渡すことです。
_var parameters = new object[1];
parameters[0] = lines;
Activator.CreateInstance(typeof(T), parameters)
_
もちろん、単純にインライン配列初期化子を使用できます。
_list.Add((T)Activator.CreateInstance(typeof(T), new object[] { lines }));
_