Csharp/CSharp Tutorial/Reflection/Method
Содержание
- 1 Call string method with reflection and Expression
- 2 Deeper Reflection: Invoking Functions
- 3 Deeper Reflection: iterate through the methods of the class
- 4 Dynamically Invoking A Method
- 5 Finding Particular Members
- 6 Inspecting a method"s body
- 7 Invoke member method with created instance from reflection
- 8 Invoke methods using reflection
- 9 List Methods
- 10 Obtain the metadata tokens
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