Invoking Methods by Using the MethodInfo Class


Invoking Methods by Using the MethodInfo Class

The Reflection API also provides the ability to search for and invoke methods that you may not have knowledge of at compile time. Before you can invoke a method, you must successfully request a MethodInfo object from the Type object. In this section we will investigate three ways to retrieve a MethodInfo from a Type object.

Working with the GetMethod Method

The easiest way to retrieve a MethodInfo object is to search for the method by name . The Type object provides the GetMethod(string methodName) to do just this. The string parameter contains the case-sensitive name of the public method to get. If you request a nonpublic method or a method that does not exist, then a null reference is returned. Beware that for overloaded methods an AmbiguousMatchException will be thrown. Listing 13.11 demonstrates how to find a specific method by name.

Listing 13.11
 C# public class Type_GetMethod {   public int m_Integer;   public string m_String;   public Type_GetMethod(int i, string s) {     m_Integer = i;     m_String = s;   }   public int GetSecretCode() {     char[] chars = m_String.ToCharArray();     int charsLength = chars.Length;     int ret = m_Integer;     for (int i = 0; i < charsLength; ++i)       ret += (int)chars[i];     return ret;   }   public static void Main() {     Type t = typeof(Type_GetMethod);     MethodInfo methodInfo = t.GetMethod("GetSecretCode");     if (methodInfo == null) {       MessageBox.Show("Could not find the GetSecretCode method.");       return;     }     MessageBox.Show(       String.Format("Found {0} method name {1}",       (methodInfo.IsPublic ? "Public" : "Non-Public"),       methodInfo.Name));   } } VB Module Module1     Public Class Type_GetMethod         Public m_Integer As Int32         Public m_String As String         Public Sub New(ByVal i As Int32, ByVal s As String)             m_Integer = i             m_String = s         End Sub         Public Function GetSecretCode() As Int32             Dim chars = m_String.ToCharArray()             Dim charsLength = chars.Length             Dim ret = m_Integer             Dim i As Int32             For i = 0 To charsLength                 ret = ret + CInt(chars(i))             Next i         End Function     End Class     Public Sub Main()         Dim tgm = New Type_GetMethod(0, 0)         Dim t = tgm.GetType()         Dim methodInfo = t.GetMethod("GetSecretCode")         Dim visibility As String         If MethodInfo Is Nothing Then             MessageBox.Show("Could not find the " & _                             "GetSecretCode method.")             Return         End If         If MethodInfo.IsPublic Then             visibility = "Public"         Else             visibility = "Non-Public"         End If         MessageBox.Show( _             String.Format("Found {0} method name {1}", _             visibility, _             methodInfo.Name))     End Sub End Module 

FIND MethodInfo OBJECTS FOR OVERLOADED METHODS

An overload of the GetMethod method exists that can also handle searching for overloaded methods. This overload allows you to look up a public method by name and by the type of parameters it accepts. Listing 13.12 demonstrates how to search for an overloaded method.

Listing 13.12
 C# public class Type_GetMethod {   public void OverloadedMethod(int param1) {   }   public void OverloadedMethod(int param1, bool param2) {   } } public class Test {   public static void Main() {     Type t = typeof(Type_GetMethod);     Type[] args = {typeof(int), typeof(bool)};     MethodInfo methodInfo = t.GetMethod("OverloadedMethod", args);     if (methodInfo == null) {       MessageBox.Show("Could not find the OverloadedMethod method.");         return;     }     MessageBox.Show(       String.Format("Found {0} method name {1}",         (methodInfo.IsPublic ? "Public" : "Non-Public"),          methodInfo.Name));   } } VB Module Module1     Public Class Type_GetMethod         Public Sub OverloadedMethod(ByVal param1 As Int32)         End Sub         Public Sub OverloadedMethod(ByVal param1 As Int32, _ ByVal param2 As Int32)         End Sub     End Class     Public Sub Main()         Dim tgm As New Type_GetMethod()         Dim t = tgm.GetType()         Dim args() = New Type() {0.GetType(), 0.GetType()}         Dim methodInfo = t.GetMethod("OverloadedMethod", args)         Dim visibility As String         If methodInfo Is Nothing Then             MessageBox.Show("Could not find the " & _                             "OverloadedMethod method.")             Return         End If         If methodInfo.IsPublic Then             visibility = "Public"         Else             visibility = "Non-Public"         End If         MessageBox.Show( _             String.Format("Found {0} method name {1}", _             visibility, _             methodInfo.Name))     End Sub End Module 

Another overload of the GetMethod method allows you to search for a method by name and by a set of binding constraints. The binding constraints are specified by passing a combination of BindingFlags values. Just like with GetType , there is a list of BindingFlags values that affects the execution of the search for the method. The BindingFlags values that affect the GetMethod method fall into two categories: those that define which methods to include in the search and those that change how the search works. Table 13.2 shows the list of BindingFlags values that define which methods to include in the search. Table 13.3 lists those that change how the search works.

Table 13.2. BindingFlags Members that Define Which Methods Are Searched via GetMethod

MEMBER

DESCRIPTION

Instance

Includes instance methods in the search

Static

Includes static methods in the search

Public

Includes public methods in the search

NonPublic

Includes private and protected methods in the search

FlattenHierarchy

Includes static methods up the class hierarchy

Table 13.3. BindingFlags Members That Change How GetMethod Searches

MEMBER

MEANING

IgnoreCase

Ignores the case of the specified name parameter

DeclaredOnly

Searches only the methods declared on the current Type and not methods that were inherited

The BindingFlags enumeration values can be bitwise combined to allow a very flexible way to customize the search for a desired method. If the request type is nonpublic or does not exist, then null will be returned. Listing 13.13 demonstrates how to find a public static method by using a case-insensitive search.

Listing 13.13
 C# public class Type_GetMethod {   public static void StaticMethod() {   }   public void InstanceMethod(){   } } public class Test {   public static void Main() {     Type t = typeof(Type_GetMethod);     BindingFlags flags =       BindingFlags.StaticBindingFlags.PublicBindingFlags.IgnoreCase;     MethodInfo methodInfo = t.GetMethod("sTaTiCmEtHoD", flags);     if (methodInfo == null) {       MessageBox.Show("Could not find the method named StaticMethod.");         return;     }     MessageBox.Show(       String.Format("Found {0} {1} method name {2}",         (methodInfo.IsPublic ? "public" : "non-public"),         (methodInfo.IsStatic ? "static" : "Instance"),          methodInfo.Name));   } } VB Module Module1     Public Class Type_GetMethod         Public Shared Sub SharedMethod()         End Sub         Public Sub InstanceMethod()         End Sub     End Class     Public Sub Main()         Dim tgm = New Type_GetMethod()         Dim t = tgm.GetType()         Dim flags = BindingFlags.Static Or _                     BindingFlags.Public Or _                     BindingFlags.IgnoreCase         Dim methodInfo = t.GetMethod("sHaReDmEtHoD", flags)         Dim visibility As String         Dim isShared As String         If methodInfo Is Nothing Then             MessageBox.Show("Could not find the SharedMethod method.")             Return         End If         If methodInfo.IsPublic Then             visibility = "Public"         Else             visibility = "Non-Public"         End If         If methodInfo.IsStatic Then             isShared = "Shared"         Else             isShared = "Instance"         End If         MessageBox.Show( _             String.Format("Found {0} {1} method name {2}", _             visibility, isShared, methodInfo.Name))     End Sub End Module 

Invoking a Method with the MethodInfo Class

Now that you have learned how to retrieve a MethodInfo object by searching over Type object, we can now investigate how to invoke that method. Much like the ConstructorInfo class, the MethodInfo class provides the Invoke method to allow users to invoke the method it reflects. The Invoke method accepts two parameters. The first parameter represents an instance of the type on which the method exists. The second parameter is an array of objects that represent the methods argument list. For methods that do not accept parameters, you can pass an empty array of objects. The Invoke method returns an object that represents the return value of the function. If the method does not have a return value, then null is returned. Listing 13.14 demonstrates how to invoke a method through a MethodInfo object.

Listing 13.14
 C# public class MethodInfo_Invoke {   public int AddParameterValues(int bar, int zoo) {        return bar + zoo;   } } public class Test {   public static void Main() {     Type t = typeof(MethodInfo_Invoke);     Type[] argTypes = {typeof(int), typeof(int)};     MethodInfo methodInfo =       t.GetMethod("AddParameterValues", argTypes);     if (methodInfo == null) {       MessageBox.Show("Could not find the AddParameterValues method.");         return;     }     MethodInfo_Invoke c = new MethodInfo_Invoke();     Object[] argValues = {1, 1};     object ret = methodInfo.Invoke(c, argValues);     if(ret == null)       MessageBox.Show("The invoked method returned null");     else       MessageBox.Show("The invoked method returned " + ret);   } } VB Module Module1     Public Class MethodInfo_Invoke         Public Function AddParameterValues(ByVal bar As Int32, _                                            ByVal zoo As Int32)             Return (bar + zoo)         End Function     End Class     Public Sub Main()         Dim mii = New MethodInfo_Invoke()         Dim t = mii.GetType()         Dim argTypes() = New Type() {0.GetType(), 0.GetType}         Dim MethodInfo = t.GetMethod("AddParameterValues", argTypes)         If MethodInfo Is Nothing Then             MessageBox.Show("Could not find the " & _                             "AddParameterValues method.")             Return         End If         Dim c As New MethodInfo_Invoke()         Dim argValues() = New Object() {1, 1}         Dim ret = MethodInfo.Invoke(c, argValues)         If ret Is Nothing Then             MessageBox.Show("The invoke method returned nothing")         Else             MessageBox.Show("The invoke method returned " & _                             ret.ToString())         End If     End Sub End Module 


Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net