Menu
Carl Camera

C# Reflection Part 6

Passing "out" Parameters

Out parameters are parameters that are expected (and in fact for C# required) to be populated by the called method. That is, the value for the out parameter is not meaningful when passed in and receives a value after the method is called.

bool GetCustName(int iCust, out string strName);

We must first create the object as covered in depth in Part 2:

Assembly assem = Assembly.LoadFrom(@"c:\path\to\file.dll");
Type typClsX = assem.GetType("Fully.Qual.ClsX",true);
object oClsX = Activator.CreateInstance(typClsX);

We now have our object and we need to find the GetCustName method shown above. Specifying an out parameter will mean sending an additional parameter modifier array to the GetMethod call. This array holds a boolean value indicating which parameters are out parameters.

ParameterModifier[] arrPmods = new ParameterModifier[1];
arrPmods[0] = new ParameterModifier(2);
arrPmods[0][0] = false; // not out
arrPmods[0][1] = true;  // out

ParameterModifiers are two-dimensional (for some reason I'm still trying to figure that out.) I suppose a parameter could be an array itself and individal array members could be both out and not out parameters but this whole setup seems nonintuitive. Anyway back to the explanation.

The first line defines the size of the arrPmods array as one. That is there is only a arrPmods[0] array and there is no arrPmods[1] array. Then we create a ParameterModifier array of size two to populate arrPmods[0]. We set the first value to false. This is perhaps optional since most likely it defaults to false. The second value we set to true to indicate that the second parameter is an out parameter.

Now we set up our Type array as usual, using the ref parameter technique described in Part 5.

System.Type[] arrTypes = new System.Type[2];
arrTypes.SetValue(Type.GetType("System.Int32"),0);
arrTypes.SetValue(Type.GetType("System.String&"),1);
MethodInfo miCusNm = typClsX.GetMethod("GetCustName",arrTypes,arrPmods);

This GetMethod call contains a new third parameter arrPmods where we indicate that the second parameter is an out parameter. With the method located, we continue along and invoke the method.

int iCustNum = 12345;

// package our parameters
object[] arrParms = new object[2];
arrParms.SetValue(iCustNum,0);
// no need to set the second parameter -- it will be filled in
bool success = (bool) miCusNm.Invoke(oClsX,arrParms);

We've retrieved the returned value as a boolean value, but where is the Customer Name string that we spent so much time setting up so we could retrieve it? It's here:

string strCustName = (string) arrParms[1];

The Snippet

// create an instansiation of an oClsx object
Assembly assem = Assembly.LoadFrom(@"c:\path\to\file.dll");
Type typClsX = assem.GetType("Fully.Qual.ClsX",true);
object oClsX = Activator.CreateInstance(typClsX);

// set the second parameter modifier value to true to 
// mark it as being an out parameter
ParameterModifier[] arrPmods = new ParameterModifier[1];
arrPmods[0] = new ParameterModifier(2);
arrPmods[0][0] = false; // not out
arrPmods[0][1] = true;  // out

// define the types of parameters in the target signature
// use a reference type for the out parameter
System.Type[] arrTypes = new System.Type[2];
arrTypes.SetValue(Type.GetType("System.Int32"),0);
arrTypes.SetValue(Type.GetType("System.String&"),1);
MethodInfo miCusNm = typClsX.GetMethod("GetCustName",arrTypes,arrPmods);

int iCustNum = 12345;

// package our parameters
object[] arrParms = new object[2];
arrParms.SetValue(iCustNum,0);
// no need to set the second parameter -- it will be filled in
bool success = (bool) miCusNm.Invoke(oClsX,arrParms);

// extract the value from the out parameter
string strCustName = (string) arrParms[1];

Summary

In this article, we learned how invoke a reflected method that uses an "out" parameter.

Comments