Csharp/CSharp Tutorial/Reflection/Method

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Call string method with reflection and Expression

<source lang="csharp">using System; using System.ruponentModel; using System.Linq.Expressions; using System.Reflection;

   class MainClass
   {
       static void Main()
       {
           MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
           var target = Expression.Parameter(typeof(string), "x");
           var methodArg = Expression.Parameter(typeof(string), "y");
           Expression[] methodArgs = new[] { methodArg };
           Expression call = Expression.Call(target, method, methodArgs);
           var lambdaParameters = new[] { target, methodArg };
           var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters);
           var compiled = lambda.rupile();
           Console.WriteLine(compiled("First", "S"));
       }
   }</source>

Deeper Reflection: Invoking Functions

<source lang="csharp">using System; using System.Reflection; class MainClass {

   public static void Main(String[] args)
   {
       string aname = "MyClass";
       
       Console.WriteLine("Loading: {0}", aname);
       Assembly a = Assembly.LoadFrom (aname);
       
       foreach (Type t in a.GetTypes())
       {
           if (t.IsClass)
           {
               Console.WriteLine("  Found Class: {0}", t.FullName);
               
               if (t.GetInterface("MyInterface") == null)
                   continue;
               
               object o = Activator.CreateInstance(t);
               
               Console.WriteLine("    Calling Process() on {0}", t.FullName);
           }
       }
   }

} //File: MyClass.cs interface MyInterface{

 void MyMethod(int i);

} class MyClass: MyInterface{

  public void MyMethod(int i){
     Console.WriteLine("i:"+i);
  }

}</source>

Deeper Reflection: iterate through the methods of the class

<source lang="csharp">using System; using System.Reflection; class MyClass {

   MyClass() {}
   static void Process()
   {
   }
   
   public int MyFunction(int i, Decimal d, string[] args)
   {
       return(0);
   }
   public int        value = 0;
   public float        log = 1.0f;
   public static int    value2 = 44;

} class MainClass {

   public static void Main(String[] args)
   {
       Console.WriteLine("Fields of MyClass");
       Type t = typeof (MyClass);
       
       Console.WriteLine("Methods of MyClass");
       foreach (MethodInfo m in t.GetMethods())
       {
           Console.WriteLine("{0}", m);
           foreach (ParameterInfo p in m.GetParameters())
           {
               Console.WriteLine("  Param: {0} {1}",
               p.ParameterType, p.Name);
           }
       }
       
   }

}</source>

Fields of MyClass
Methods of MyClass
Int32 MyFunction(Int32, System.Decimal, System.String[])
  Param: System.Int32 i
  Param: System.Decimal d
  Param: System.String[] args
System.Type GetType()
System.String ToString()
Boolean Equals(System.Object)
  Param: System.Object obj
Int32 GetHashCode()

Dynamically Invoking A Method

<source lang="csharp">using System; using System.Collections.Generic; using System.Reflection; using System.Text;

   public class Tester
   {
       public static void Main()
       {
           Type theMathType = Type.GetType("System.Math");
           Type[] paramTypes = new Type[1];
           paramTypes[0] = Type.GetType("System.Double");
           MethodInfo CosineInfo = theMathType.GetMethod("Cos", paramTypes);
           Object[] parameters = new Object[1];
           parameters[0] = 45 * (Math.PI / 180); 
           Object returnVal = CosineInfo.Invoke(theMathType, parameters);
           Console.WriteLine(returnVal);
       }
   }</source>

Finding Particular Members

<source lang="csharp">using System; using System.Collections.Generic; using System.Reflection; using System.Text;

   public class Tester
   {
       public static void Main()
       {
           Type theType = Type.GetType("System.Reflection.Assembly");
           MemberInfo[] mbrInfoArray = theType.FindMembers(
                               MemberTypes.Method,
                               BindingFlags.Public |
                               BindingFlags.Static |
                               BindingFlags.NonPublic |
                               BindingFlags.Instance |
                               BindingFlags.DeclaredOnly,
                               Type.FilterName, "Get*");
           foreach (MemberInfo mbrInfo in mbrInfoArray)
           {
               Console.WriteLine("{0} is a {1}",
                               mbrInfo, mbrInfo.MemberType);
           }
       }
   }</source>

Inspecting a method"s body

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       MethodInfo m = typeof(object).GetMethod("ToString");
       MethodBody mb = m.GetMethodBody();
       byte[] ilb = mb.GetILAsByteArray();
       for (int i = 0; i < ilb.Length; i++)
           Console.Write("{0:X} ", ilb[i]);
   }

}</source>

2 28 9 0 0 6 6F 2 0 0 6 2A

Invoke member method with created instance from reflection

<source lang="csharp">using System; using System.Reflection; using System.Globalization;

 class Class1
 {
   DateTime[] dateTimes = new DateTime[10];
   public DateTime this[int index]
   {
     get{ return dateTimes[index]; }
     set{ dateTimes[index] = value;}
   }
   
   
   private DateTime dateOfBirth;
   public DateTime DateOfBirth
   {
       get{ return dateOfBirth; }
       set{ dateOfBirth = value; }
   }
     
   public void Test()
   {
     Console.WriteLine("Test method called");
   }
   
   
   private string field;
   
   public string Property
   { 
     get{ return field; }
     set{ field = value; }
   }
   
 }
   class MainClass{
   
   static void Main(string[] args)
   {
     Type type = Type.GetType("Class1");
     object o = Activator.CreateInstance(type);
     
     type.InvokeMember("Test", BindingFlags.InvokeMethod,null, o, new object[]{});
     
     // Using a ConstructorInfo
     ConstructorInfo constructorInfo = type.GetConstructor(new Type[]{});
       
     o = constructorInfo.Invoke(new object[]{});
     
     type.InvokeMember("Test", BindingFlags.InvokeMethod,null, o, new object[]{});
     
     // Type.InvokeMember
     o = type.InvokeMember("Class1", BindingFlags.CreateInstance, null, null, new object[]{});
     
     type.InvokeMember("Test", BindingFlags.InvokeMethod,null, o, new object[]{});
   }
   }</source>

Invoke methods using reflection

<source lang="csharp">using System; using System.Reflection;

class MyClass {

 public MyClass(int i, int j) { 
   Console.WriteLine("MyClass(int i, int j)");
   Console.WriteLine(i);
   Console.WriteLine(j);
 } 

 public int sum() { 
   Console.WriteLine("sum");
   return 0; 
 } 

 public bool isBetween(int i) { 
   Console.WriteLine("isBetween");
   return false; 
 } 

 public void set(int a, int b) { 
   Console.Write("Inside set(int, int). "); 
 } 

 public void set(double a, double b) { 
   Console.Write("Inside set(double, double). "); 
 } 

 public void show() { 
   Console.WriteLine("show"); 
 } 

}

class MainClass {

 public static void Main() { 
   Type t = typeof(MyClass);   
   MyClass reflectOb = new MyClass(10, 20); 
   int val; 

   Console.WriteLine("Invoking methods in " + t.Name);     
   Console.WriteLine(); 
   MethodInfo[] mi = t.GetMethods(); 

   // Invoke each method. 
   foreach(MethodInfo m in mi) { 
     // Get the parameters. 
     ParameterInfo[] pi = m.GetParameters(); 

     if(m.Name.rupareTo("set")==0 && 
        pi[0].ParameterType == typeof(int)) { 
       object[] args = new object[2]; 
       args[0] = 9; 
       args[1] = 18; 
       m.Invoke(reflectOb, args); 
     } 
     else if(m.Name.rupareTo("set")==0 && 
        pi[0].ParameterType == typeof(double)) { 
       object[] args = new object[2]; 
       args[0] = 1.12; 
       args[1] = 23.4; 
       m.Invoke(reflectOb, args); 
     } 
     else if(m.Name.rupareTo("sum")==0) { 
       val = (int) m.Invoke(reflectOb, null); 
       Console.WriteLine("sum is " + val); 
     } 
     else if(m.Name.rupareTo("isBetween")==0) { 
       object[] args = new object[1]; 
       args[0] = 14; 
       if((bool) m.Invoke(reflectOb, args)) 
         Console.WriteLine("14 is between x and y"); 
     } 
     else if(m.Name.rupareTo("show")==0) { 
       m.Invoke(reflectOb, null); 
     } 
   } 
 } 

}</source>

MyClass(int i, int j)
10
20
Invoking methods in MyClass
sum
sum is 0
isBetween
Inside set(int, int). Inside set(double, double). show

List Methods

<source lang="csharp">using System; using System.Reflection; public interface IFaceOne {

 void MethodA();

} public interface IFaceTwo {

 void MethodB();

} public class MyClass: IFaceOne, IFaceTwo {

 public enum MyNestedEnum{}
 
 public int myIntField;
 public string myStringField;
 public void myMethod(int p1, string p2)
 {
 }
 public int MyProp
 {
   get { return myIntField; }
   set { myIntField = value; }
 }
 void IFaceOne.MethodA(){}
 void IFaceTwo.MethodB(){}

} public class MainClass {

 public static void Main(string[] args)
 {
   MyClass f = new MyClass();
   Type t = f.GetType();
   MethodInfo[] mi = t.GetMethods();
   foreach(MethodInfo m in mi)
     Console.WriteLine("Method: {0}", m.Name);
   
 }

}</source>

Method: myMethod
Method: get_MyProp
Method: set_MyProp
Method: GetType
Method: ToString
Method: Equals
Method: GetHashCode

Obtain the metadata tokens

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Type typeInfo = typeof(object);
       MethodInfo methInfo = typeInfo.GetMethod("ToString");
       ModuleHandle moduleHandle = methInfo.Module.ModuleHandle;
       int typeToken = typeInfo.MetadataToken;
       int methToken = methInfo.MetadataToken;
       Console.WriteLine("Token: {0}", methToken);
   }

}</source>

Token: 100663298