Csharp/CSharp Tutorial/Reflection/Method

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

Call string method with reflection and Expression

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"));
        }
    }

Deeper Reflection: Invoking Functions

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);
   }
}

Deeper Reflection: iterate through the methods of the class

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);
            }
        }
        
    }
}
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

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);
        }
    }

Finding Particular Members

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);
            }
        }
    }

Inspecting a method"s body

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]);
    }
}
2 28 9 0 0 6 6F 2 0 0 6 2A

Invoke member method with created instance from reflection

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[]{});
    }
    }

Invoke methods using reflection

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); 
      } 
    } 
  } 
}
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

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);
    
  }
}
Method: myMethod
Method: get_MyProp
Method: set_MyProp
Method: GetType
Method: ToString
Method: Equals
Method: GetHashCode

Obtain the metadata tokens

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);
    }
}
Token: 100663298