2

I have a method as shown below...

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

    }

I have to call this method using Reflection, because of the way the entire framework is setup.

Here is the code I'm using to call it

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

This is returning me MissingMethodException saying the method Fit.TcpConnector.MakeRequest is not found.

However, if I change the signature of the MakeRequest to

  public bool MakeRequest(string args)

instead of

  public bool MakeRequest(string[] args)

then, it is working. Can anybody point me in right direction in calling the function which takes array as its parameter?

2
  • Why are you using Hungarian notation? It's not very useful, since the compiler already checks the types. Commented Mar 7, 2012 at 15:55
  • I have been thinking exactly same. May be too much vbscripting made me follow it. But, now I'm feeling like I shouldn't. Your question inspired me to relook at leaving that notation. Commented Mar 7, 2012 at 16:03

5 Answers 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.

Sign up to request clarification or add additional context in comments.

Comments

5

You have to pass it an array that contains your array:

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

That's because each item in the array you pass to the method represents one parameter to the function. And since you function has one parameter of type string[], you need to give it an array that contains one item of type string[].

That being said, I think using GetMethod() and Invoke() is clearer than InvokeMember():

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

Your incorrect code compiles because of array covariance as Eric Lippert pointed out in his answer.

Comments

4

You simply need to put the string arguments into a object-array.

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

The reason why you need to do this is the point that InvokeMember takes a object-array as parameter, so your string array is converted into a object array and each string is threaten as a single parameter.

Comments

1

Your innerargs value is wrong.

In innerargs array each object represents one parameter

so you really should make

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

object[] arg = {innerargs];

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

Or somesuch.

Comments

1

The args argument is an array of arguments to pass to the member, so if your member argument is an array you need to wrap it in another array, otherwise it assumes you are just sending a single string argument:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.