Home   Cover Cover Cover Cover
 

Reflection

Example "Assembly"

In this example, the assembly mscorlib.dll is loaded. It contains many of the base classes of the .NET library. After a successful loading the metadata about these classes can be queried. The following code lists all the types of the assembly a on the console.

/book/samples/4/Reflection/AssemblyExample.cs
using System;
using System.Reflection;

namespace Kapitel4.Reflection {

  public class AssemblyExample {
    public static void Main(string[] argv) {
      Assembly a = Assembly.Load("mscorlib");
      Type[] types = a.GetTypes();
      foreach (Type t in types)
        Console.WriteLine(t.FullName);
    }
  }
}




Example "Type"

As soon as one has a Type object one can obtain meta-information about its elements, as shown in the following examples:

/book/samples/4/Reflection/TypeExample.cs
using System;
using System.Reflection;

namespace Kapitel4.Reflection {

  public class TypeExample {
    public static void Main(string[] argv) {
      string s = "Hello";
      Type t = s.GetType();
      Console.WriteLine("type: {0}", t.FullName);
      Console.WriteLine("direct base type: {0}", t.BaseType);
      Console.WriteLine("implemented interfaces:");
      foreach (Type i in t.GetInterfaces()) Console.WriteLine("\t{0}", i.FullName);
      Console.WriteLine("public constructors:");
      foreach (ConstructorInfo i in t.GetConstructors()) Console.WriteLine("\t{0}", i);
      Console.WriteLine("public properties:");
      foreach (PropertyInfo i in t.GetProperties()) Console.WriteLine("\t{0}", i);
    }
  }
}




Example "Activator"

In the call Activator.CreateInstance(type, args) arguments in the form of an object array can be passed. These arguments serve to choose the correct constructor. Here is an example:

/book/samples/4/Reflection/ActivatorExample.cs
using System;
using System.Reflection;

namespace Kapitel4.Reflection {

  public class ActivatorExample {
    public static void Main(string[] argv) {
      Type t = Type.GetType("System.String");
      object[] args = new object[] { new char[]{'T','e','s','t'} };
      string s = (string) Activator.CreateInstance(t, args);
      Console.WriteLine(s);
    }
  }
}




Example "Search for methods"

One can also limit the search by using flags. For example, if one only wants to search for static methods that are declared public, one can write

/book/samples/4/Reflection/MethodExample.cs
using System;
using System.Reflection;



  public class MethodExample {
    public static void Main(string[] argv) {
      Type t = typeof(System.String);
      MethodInfo[] methods = t.GetMethods();
      foreach (MethodInfo m in methods) Console.WriteLine(m);
      foreach (MethodInfo m in methods) Console.WriteLine(m);
      Type t = typeof(string);
      MethodInfo[] methods = t.GetMethods(BindingFlags.Static | BindingFlags.Public);
      foreach (MethodInfo m in methods) Console.WriteLine(m);
    }
  }




Example "Dynamic invocation of a method"

The following example shows this process, from the search for the methods, through the dynamic object creation to the dynamic call of the method found:

/book/samples/4/Reflection/MethodInvokeExample.cs
using System;
using System.Reflection;



  public class MethodInvokeExample {
    public static void Main(string[] argv) {
      //----- create a String object
      Type t = typeof(string);
      object[] args = new object[] { new char[] {'F','o','O','B','A','r'} };
      string s = (string) Activator.CreateInstance(t, args);
      Console.WriteLine("s before invoking method s.ToLower(): {0}", s);
      //----- search for and invoke s.ToLower()
      MethodInfo method = t.GetMethod("ToLower", new Type[0]); // no parameters
      object result = method.Invoke(s, new object[0]); // no parameters
      Console.WriteLine("result of method s.ToLower(): {0}", result);
      
      // String object s taken from previous example ("FoOBAr").
      Type[] parTypes = { typeof(char), typeof(int) }; 
      MethodInfo method = t.GetMethod("IndexOf", parTypes);
      object[] parameters = { 'B', 1 };
      object result = method.Invoke(s, parameters);
      Console.WriteLine("result of method s.IndexOf(�B�, 1): {0}", result);
    }
  }




Beispiel "Dynamic creation of an assembly at runtime"

As a small example we show here how a class HelloWorld can be created dynamically and its method SayHelloTo executed:

/book/samples/4/Reflection/EmitExample.cs
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

namespace Kapitel4.Reflection {

  public class EmitExample {
    public static void Main(string[] argv) {
      //----- create an assembly
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = "HelloWorldAssembly";
      AssemblyBuilder newAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly
            (assemblyName, AssemblyBuilderAccess.Run);
      //----- create a module within the new assembly
      ModuleBuilder newModule = newAssembly.DefineDynamicModule("HelloWorldModule");
      //----- create a type within the new module
      TypeBuilder newType = newModule.DefineType("HelloWorld", TypeAttributes.Public);
      //----- create a method with its signature in the new type
      Type[] paramTypes = { typeof(string) };
      Type retType = typeof(string);
      MethodBuilder newMethod = newType.DefineMethod("SayHelloTo",
          MethodAttributes.Public | MethodAttributes.Virtual, retType, paramTypes);
      //----- insert CIL instructions into the new method
      ILGenerator ilGen = newMethod.GetILGenerator();
      ilGen.Emit(OpCodes.Ldstr, "Hello ");
      ilGen.Emit(OpCodes.Ldarg_1);
      Type t = typeof(string);
      MethodInfo mi = t.GetMethod("Concat", new Type[] { typeof(string),typeof(string) });
      ilGen.Emit(OpCodes.Call, mi);
      ilGen.Emit(OpCodes.Ret);
      //----- finish new type
      newType.CreateType();
      //----- execute the newly created method SayHelloTo("Wolfgang")
      MethodInfo method = newType.GetMethod("SayHelloTo", new Type[] { typeof(string) });
      object obj = Activator.CreateInstance(newType);
      object result = method.Invoke(obj, new string[] {"Wolfgang"});
      Console.WriteLine(result);
    }
  }
}