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

    }

由于整个框架的设置方式,我必须使用反射调用此方法。

这是我用来调用它的代码

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

这返回了 MissingMethodException,说找不到 Fit.TcpConnector.MakeRequest 方法。

但是,如果我将 MakeRequest 的签名更改为

  public bool MakeRequest(string args)

代替

  public bool MakeRequest(string[] args)

然后,它正在工作。任何人都可以在调用以数组作为参数的函数时指出我正确的方向吗?

4

5 回答 5

6

C# supports array element type covariance on arrays where the element type is a reference type. That is, you can automatically convert string[] to object[].

So what is happening here is you are passing an array of strings, and the runtime is saying "ah, there's that array of objects I was expecting", and now each string is being passed as an argument, rather than passing the array of strings as an argument.

The trick is to make an array of objects that contains the array of strings, rather than one that is identical to the array of strings.

于 2012-03-07T15:53:04.740 回答
5

您必须向它传递一个包含您的数组的数组:

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

这是因为传递给方法的数组中的每一项都代表函数的一个参数。由于你的函数有一个类型的参数string[],你需要给它一个包含一个类型项的数组string[]

话虽如此,我认为使用GetMethod()andInvoke()InvokeMember()

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

正如 Eric Lippert 在他的回答中指出的那样,由于数组协方差,您的错误代码会编译。

于 2012-03-07T15:50:17.527 回答
4

您只需将字符串参数放入object-array 中。

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

您需要这样做的原因是InvokeMemberobject-array 作为参数,因此您的字符串数组被转换为对象数组,并且每个字符串都被威胁为单个参数。

于 2012-03-07T15:48:27.273 回答
1

你的 innerargs 值是错误的。

在 innerargs 数组中,每个对象代表一个参数

所以你真的应该做

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 回答