REFLECTION ON A METHOD WITH AN OUT PARAMETER


Reflectionでoutパラメータを実行する方法
As I code my commercial Dynamic Data libraries for ASP.NET 4 support, I’ve elected to deliver one assembly compiled under .net 3.5 SP 1 that also supports new features of ASP.NET 4. 3.5SP1 is the initial release of Dynamic Data. To interact with the new properties and methods in ASP.NET 4, I am using .net Reflection.
I have long used .net reflection, so I didn’t think there were many more things to learn. Today I encountered a new case, a method that has an out parameter.
Here’s the method I wanted to call. It's on the class System.Web.DynamicData.DynamicDataExtensions:
public static bool TryGetMetaTable(this INamingContainer control, out MetaTable table);

To call a function using .reflection, you take these actions:
  • Call a GetMethod(“methodname”) method on the specific type.
  • Call the Invoke method on the MethodInfo object that was returned by GetMethod.

  • If this function did not have an out parameter, the code would look like this:
    Type[] vTypes = new Type[] { typeof(INamingContainer), typeof(MetaTable) };
    MethodInfo vTGMTMI = typeof(DynamicDataExtensions).GetMethod("TryGetMetaTable", BindingFlags.Public | BindingFlags.Static,  
       null,  vTypes, null);
    if (vTGMTMI == null)
       throw new NotImplementedException("Must use ASP.NET 4.0 or higher.");
    
    object[] vParms = new object[] { GridView, null };
    bool vResult = (bool) vTGMTMI.Invoke(null, BindingFlags.InvokeMethod, null, vParms, null);
    if (vResult)
      // metatable returned is in vParms[1]
    

    The GetMethod() method gets more complex with that 
    out parameter. You must pass the output parameter TYPE as a reference to the intended type.
     
    Approach 1 - Using Type.MakeByRefType
    As pointed out in the comments, the Type class has the tools needed.  Use the method  MakeByRefType() like this:
    Type[] vTypes = new Type[] { typeof(INamingContainer), typeof(MetaTable).MakeByRefType() };

     
    Approach 2 - Using GetType("string") 
    Before learning of the MakeByRefType() method, I used this technique. I wanted to keep it in the post because I educates on how to use GetType("string") for an 
    out parameter. 
    Pass the fully qualified type name into the  Type.GetType(“string of the type”) method. The type within the string must be:
  • full name
  • end with “&” to indicate its a pointer

  • Here is the MetaTable class as a full qualified name, including type, &, and assembly name:
    Type.GetType("System.Web.DynamicData.MetaTable&, System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
    Here’s the corrected code, allowing the MetaTable's type supply both full names.
    Type vMetaTableP = Type.GetType(typeof(MetaTable).FullName + "&," + typeof(MetaTable).Assembly.FullName);
    Type[] vTypes = new Type[] { typeof(INamingContainer), vMetaTableP };
    
    

    The big trick is to avoid using typeof(MetaTable).AssemblyQualifiedName, because it omits the “&”.
    Putting it all together 
    This is the complete code using my preferred solution, MakeByRefType().
    Type[] vTypes = new Type[] { typeof(INamingContainer), typeof(MetaTable).MakeByRefType() };
    
    MethodInfo vTGMTMI = typeof(DynamicDataExtensions).GetMethod("TryGetMetaTable", BindingFlags.Public | BindingFlags.Static,  
       null,  vTypes, null);
    if (vTGMTMI == null)
       throw new NotImplementedException("Must use ASP.NET 4.0 or higher.");
    
    object[] vParms = new object[] { GridView, null };
    bool vResult = (bool) vTGMTMI.Invoke(null, BindingFlags.InvokeMethod, null, vParms, null);
    if (vResult)
      // metatable returned is in vParms[1]
    

    Note that the GetMethod takes a parameter of type ParameterModifier. It certainly is involved with out parameters, but only when calling COM functions. In this case, the last parameter for GetMethod is null instead of a ParameterModifier array.