2

私は以下に示すような方法を持っています...

public bool MakeRequest(string[] args)
    {
        try
        {
            sXmlRequest = args[0];
            sResponse = "";
            Console.WriteLine(sXmlRequest);
            sw.Write(sXmlRequest);
            sw.Flush();
            sResponse = sr.ReadToEnd();
            return true;
        }
        catch (Exception e)
        {
            sResponse = e.Message;
            return false;
        }

    }

フレームワーク全体のセットアップ方法のため、Reflection を使用してこのメ​​ソッドを呼び出す必要があります。

ここに私がそれを呼び出すために使用しているコードがあります

string[] innerargs = {"Dummy Args"};
string pAssembly = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\TCPConnector.dll";
Assembly assemblyInstance = Assembly.LoadFrom(pAssembly);
Type tConnector = assemblyInstance.GetType("Fit.TcpConnector");
Object oLateBound = assemblyInstance.CreateInstance(tConnector.FullName);

result = tConnector.InvokeMember("MakeRequest", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, oLateBound, innerargs);

これは、メソッド Fit.TcpConnector.MakeRequest が見つからないという MissingMethodException を返しています。

ただし、MakeRequest の署名を次のように変更すると、

  public bool MakeRequest(string args)

それ以外の

  public bool MakeRequest(string[] args)

その後、それは働いています。配列をパラメーターとして受け取る関数を呼び出す際に、誰かが私を正しい方向に向けることができますか?

4

5 に答える 5

6

C# は、要素の型が参照型である配列で、配列要素の型の共分散をサポートします。つまり、自動的に に変換できstring[]ますobject[]

ここで何が起こっているかというと、文字列の配列を渡すと、ランタイムが「ああ、私が期待していたオブジェクトの配列がある」と言って、文字列の配列を渡すのではなく、各文字列が引数として渡されます。引数として。

トリックは、文字列の配列と同一のものではなく、文字列の配列を含むオブジェクトの配列を作成することです。

于 2012-03-07T15:53:04.740 に答える
5

配列を含む配列を渡す必要があります。

tConnector.InvokeMember(
    "MakeRequest",
    BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
    null, oLateBound, new object[] { innerargs });

これは、メソッドに渡す配列内の各項目が関数の 1 つのパラメーターを表すためです。また、関数には type のパラメーターが 1 つstring[]あるため、 type の項目を 1 つ含む配列を渡す必要がありますstring[]

GetMethod()そうは言っても、 andを使用するInvoke()方がより明確だと思いますInvokeMember()

var makeRequestMethod = tConnector.GetMethod("MakeRequest");
makeRequestMethod.Invoke(oLateBound, new object[] { innerargs });

Eric Lippert が回答で指摘したように、配列の共分散が原因で間違ったコードがコンパイルされます。

于 2012-03-07T15:50:17.527 に答える
4

文字列引数を配列に入れるだけですobject

new Object[] { new String[] { "Mytext" } }

これを行う必要がある理由InvokeMemberは、object-array をパラメーターとして受け取る点にあるため、文字列配列がオブジェクト配列に変換され、各文字列が単一のパラメーターとして脅かされます。

于 2012-03-07T15:48:27.273 に答える
1

innerargs の値が間違っています。

innerargs 配列では、各オブジェクトが 1 つのパラメーターを表します

だからあなたは本当に作るべきです

string[] innerargs = {"Dummy Args"};

object[] arg = {innerargs];

result = tConnector.InvokeMember("MakeRequest", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, oLateBound, arg );

または何か。

于 2012-03-07T15:50:42.330 に答える
1

args 引数はメンバーに渡す引数の配列であるため、メンバー引数が配列である場合は別の配列でラップする必要があります。それ以外の場合は、単一の文字列引数を送信していると見なされます。

result = tConnector.InvokeMember("MakeRequest", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, oLateBound, new object[] { innerargs });
于 2012-03-07T15:51:03.333 に答える