Csharp/CSharp Tutorial/Reflection/Constructor

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

Dynamically invoking constructors

<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()
   {
       ConstructorInfo ci = typeof(string).GetConstructor(new Type[] { typeof(char[]) });
       string s = (string)ci.Invoke(new object[] {new char[] { "H", "e", "l", "l", "o" } });
       Console.WriteLine(s);
   }

}</source>

Hello

Find matching constructor

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

class MyClass {

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

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

 public int sum() { 
   return 0; 
 } 

 public bool isBetween(int i) { 
   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("Values"); 
 } 

}

class MainClass {

 public static void Main() { 
   Type t = typeof(MyClass); 
   int x; 
   // Find matching constructor. 
   ConstructorInfo[] ci = t.GetConstructors(); 

   for(x=0; x < ci.Length; x++) { 
     ParameterInfo[] pi =  ci[x].GetParameters(); 
     if(pi.Length == 2) break; 
   } 

   if(x == ci.Length) { 
     Console.WriteLine("No matching constructor found."); 
     return; 
   } 
   else 
     Console.WriteLine("Two-parameter constructor found.\n"); 

 } 

}</source>

Two-parameter constructor found.

Get constructor information: Display return type, name and parameters

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

class MyClass {

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

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

 public int sum() { 
   return 0; 
 } 

 public bool isBetween(int i) { 
   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("Values"); 
 } 

}

class MainClass {

 public static void Main() { 
   Type t = typeof(MyClass); 

   // Get constructor info. 
   ConstructorInfo[] ci = t.GetConstructors(); 

   Console.WriteLine("Available constructors: "); 
   foreach(ConstructorInfo c in ci) { 
     // Display return type and name. 
     Console.Write("   " + t.Name + "("); 

     // Display parameters. 
     ParameterInfo[] pi = c.GetParameters(); 

     for(int i=0; i < pi.Length; i++) { 
       Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name); 
       if(i+1 < pi.Length) 
          Console.Write(", "); 
     } 

     Console.WriteLine(")"); 
   } 
   Console.WriteLine(); 
 } 

}</source>

Available constructors:
   MyClass(Int32 i)
   MyClass(Int32 i, Int32 j)

Using a ConstructorInfo to create new instance

<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>

Utilize MyClass without assuming any prior knowledge: invoke constructor

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

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

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

 public int sum() { 
   return 0; 
 } 

 public bool isBetween(int i) { 
   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("Values"); 
 } 

}

class MainClass {

 public static void Main() { 
   Assembly asm = Assembly.LoadFrom("main.exe"); 

   Type[] alltypes = asm.GetTypes(); 

   Type t = alltypes[0]; // use first class found 

   Console.WriteLine("Using: " + t.Name); 

   ConstructorInfo[] ci = t.GetConstructors(); 

   // Use first constructor found. 
   ParameterInfo[] cpi = ci[0].GetParameters(); 
   object reflectOb; 

   if(cpi.Length > 0) { 
     object[] consargs = new object[cpi.Length]; 

     // initialize args 
     for(int n=0; n < cpi.Length; n++) 
       consargs[n] = 10 + n * 20; 

     // construct the object 
     reflectOb = ci[0].Invoke(consargs); 
   } else 
     reflectOb = ci[0].Invoke(null); 
    
 } 

}</source>

Using: MyClass
Constructing MyClass(int).