Sample sharing for the best combination of reflection and dynamic in C #

Source: Internet
Author: User
This article mainly describes the C # reflection and dynamic Best combination sample code, the need for friends can refer to the following

In C #, reflection technology is widely used, as for what is reflection ... If you do not understand, please look at the next paragraph, otherwise please skip the next paragraph. Advertising: Like my article friends please pay attention to my blog, which also helps to improve my writing motivation.

Reflection: When you turn your back on a beautiful woman or a handsome man, but you can not return to look closely at the study (purely fictitious, if there is coincidence, purely identical), a small mirror can meet your needs. A similar situation is often encountered in C # programming: There is a DLL class library that someone else has written that you want to use without program documentation ... With the functionality provided by C # Runtime, you can load the DLL class library into your program and look at every part of the DLL, which is reflected in C #.

The most prominent advantage or rationality of reflection: to realize the dynamic adjustment of program function without modifying the program's original code (runtime dynamic object creation)

Example:


Interface Irun {  void Run ()} class Person:irun {public  void run ()  {   Console.WriteLine ("Go, go lol!") ");  } } Class Car:irun {public  void Run ()  {   Console.WriteLine ("Woo ... ...");}  } Class Program {  static void Main (string[] args)  {   Irun e = new Person ();   E.run ();   Console.ReadLine ();  } }

If the run function above is not necessarily performed by person, sometimes it needs to be car and sometimes requires person. The common solution is to add the if and other judgment structures as follows:


static void Main (string[] args)  {   Console.WriteLine ("Please enter: Car or person");   String type = Console.ReadLine ();   Irun e = null;   if ("Car" = = Type)   {    e = new Car ();   } else if (' person ' = = type)   {    e = new Person ();   }   if (null! = e)    e.run ();   Console.ReadLine ();  }

This structure solves the present demand, but it is not robust. With the implementation of the Irun interface and the inheritance of related classes, the above judgment structure will increase rapidly. Object-oriented programming, design patterns are followed by a major principle is the package transformation, so the above program does not respond well to change. We do not refer to the "design pattern" knowledge here, so the following example code is intended only to simplify the above program and not to deliberately apply the knowledge of design patterns. As follows:


static void Main (string[] args)  {   Console.WriteLine ("Please enter: Car or person");   String type = Console.ReadLine ();   String classPath = String.Format ("namespace.{ 0} ", type);   Irun e = Activator.CreateInstance (null, ClassPath). Unwrap () as Irun;   if (null! = e)    e.run ();   Console.ReadLine ();  }

After the above modification, the program can be self-based on the user's input, through the activator.createinstance to create an instance of Irun, the program here will no longer with the irun of the implementation of the issue of the impact of the change. The above advantages are obtained through reflection, which is what I think of as "the rationality of Reflection existence".

Activator, Assembly to implement reflection mode to create objects

The reflection mode creation object in C # can be implemented by Activator.CreateInstance (static) and assembly.createinstance (non-static), where assembly.createinstance Internal calls are still activator.createinstance.

Depending on whether the type object you want to dynamically create is in the current assembly, you can divide the reflection creation object into: Creating Type objects within an assembly and type objects outside the assembly.

To create a type object within an assembly


  private static void ReflectionIRun1 (string className)  {   string classPath = String.Format ("namespace.{ 0} ", className);   The parameter, NULL, indicates that the type object being created is in the current assembly    var handler = Activator.CreateInstance (null, classPath);   Irun e = (irun) handler. Unwrap ();   Console.WriteLine (E.run ());  }  private static void ReflectionIRun2 (string className)  {   string classPath = String.Format ("namespace.{ 0} ", className);   typeof (Irun). Assembly gets the assembly containing the Irun type   object obj = typeof (Irun). Assembly.createinstance (null, classPath);   Irun e = (irun) obj;   Console.WriteLine (E.run ());  }

To create a type object outside the assembly

Add a class library (another assembly) to the project, such as:

Add a Boss class, as follows:


Namespace lib{public class Boss {  private string name = "eldest brother";    public string name{   get {return Name;}  }  public string Talk ()  {   return "you have all been expelled ...";  }  The boss will not settle the accounts, always pay more money, so very self-aware of the payfor set to private, prevent external personnel call  private int payfor (int total)  {   return total + ten;  } }}

Before getting a Boss object, first add a reference to Lib, and get an example as follows:


private static void ReflectionBoss1 ()  {   string classPath = "Lib.boss";   The "Lib" parameter indicates the assembly to be loaded (that is, the type of object to be created is defined in which assembly)   var handler = activator.createinstance ("Lib", ClassPath);   Boss B = Handler. Unwrap () as Boss;   Console.WriteLine (B.talk ());  }  private static void ReflectionBoss2 ()  {   string classPath = "Lib.boss";   Assembly.Load ("Lib") loads the assembly (that is, the type of object to be created is defined in which assembly)   var Assembly = Assembly.Load ("Lib");   Boss B = (boss) assembly. CreateInstance (ClassPath);   Console.WriteLine (B.talk ());  }

Refer to MSDN for reflection-related knowledge about how the CLR finds and locates assemblies to load when reflecting.

Reflection access fields, calling methods (properties)

Reflection can help us to dynamically create objects, but also help us to dynamically access the object's methods (properties) or fields, because the C # version of the different methods will have changes or extensions, more in-depth content, please refer to MSDN. The following is a simple example (standard usage).

Renaming the Boss, example:


private static void ReflectionBoss1 ()  {   string classPath = "Lib.boss";   The "Lib" parameter indicates the assembly to be loaded (that is, the type of object to be created is defined in which assembly)   var handler = activator.createinstance ("Lib", ClassPath);   Boss B = Handler. Unwrap () as Boss;   Key code   FieldInfo f = b.gettype (). GetField ("name", Bindingflags.getfield | BindingFlags.NonPublic | bindingflags.instance);   F.setvalue (b, "Xiao er");   Console.WriteLine ("{0}:{1}", B.name, B.talk ());  }

Output:

Let the boss pay:


private static void ReflectionBoss1 ()  {   string classPath = "Lib.boss";   The "Lib" parameter indicates the assembly to be loaded (that is, the type of object to be created is defined in which assembly)   var handler = activator.createinstance ("Lib", ClassPath);   Boss B = Handler. Unwrap () as Boss;   Key code   MethodInfo method = B.gettype (). GetMethod ("Payfor", BindingFlags.InvokeMethod | BindingFlags.NonPublic | bindingflags.instance);   Object Money = method. Invoke (b, new object[] {ten});   Console.WriteLine ("DW039: eldest brother to reimburse me 10 yuan money fare ...");   Console.WriteLine ("{0}: ..., it's not clear, give you these." ", b.name);   Console.WriteLine ("DW039: ...");   Console.WriteLine ("{0}:{1}", B.name,money);   Console.WriteLine ("DW039: Boss you are awesome!");  }

Output:

Dynamic and reflective double swords

Because reflection is a type operation at run time, you are faced with an issue of type uncertainty when programming. According to the previous article, "C # Anonymous object (anonymous type), VAR, dynamic type dynamically," dynamic type combined with the reflection program we write, you can greatly optimize the program logic (access to the protected level limit code is not within this scope).

Optimization of the above code:


private static void ReflectionBoss1 ()  {   string classPath = "Lib.boss";   var handler = activator.createinstance ("Lib", ClassPath);   Dynamic B = handler. Unwrap ();   Console.WriteLine (B.talk ());  }  private static void ReflectionBoss2 ()  {   string classPath = "Lib.boss";   var assembly = Assembly.Load ("Lib");   Dynamic B = assembly. CreateInstance (ClassPath);   Console.WriteLine (B.talk ());  }

Using dynamic type Object B to invoke reflection gets the properties of the object, methods can be called directly, thus eliminating the frequent type conversion operations.

Reflection of common application scenarios

Application scenario What impresses me most is the MS PetShop example, which reflects a different data access layer when switching from a SQL Server database to an Oracle database. However, I have never experienced switching between databases in my actual project, and other scenarios are basically similar to the example above. If friends you find more application scenarios, please give supplement, 3ks.

Advantages and disadvantages of reflection

Pros: Reflection makes the program more flexible

Cons: Reflection runs relatively slowly

As the reflection is slower than the normal program, I have not tested it and I am not going to do it. The reality is that Ms advocates the use of dynamic, MVC prevalence, MS-to-CLR optimization, and machine performance improvements, so you don't need to worry too much about reflection performance in development. If you write a program run speed bottlenecks (should first ensure that their program is reasonable), study the database optimization, data caching, Web caching, load balancing technology I think more practical.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.