web-dev-qa-db-ja.com

型のコンストラクターが見つかりません

例外メッセージ: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つのクラスで機能しますが、唯一の違いは入力数です。

25
Jacob Lambert

これは、コンストラクタパラメータのリストを含むことになっているオブジェクト配列を受け入れる _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 }));
_
46
Groo