 
 Reflection is an important mechanism in C# that allows to get information about the members and every member’s type(class, structure, delegate, interface, enum, etc.) from a program or assembly(dll, exe) at runtime.
Pros: Reflection improves theflexibilityandextensibilityof the program,reduces the couplingandimproves the adaptability. It allows programs to create and control objects of any class without hard-coding the target class in advance.
Cons: Reflection is veryslow, and make the internal logic of the program morecomplex, and hard toreadandmaintain.
The System.Type class plays a central role in reflection. It represents the instance of the target Class, and provides all the methods of getting the type information from the target class.
typeof() operation:  Type t = typeof(string);
GetType() method:  string s = "grayworm";
 Type t = s.GetType(); 
Type.Name: Get the Type’s nameFullName: Get full names of the Type(include namespace)Namespace: Get the NameSpace nameIsAbstract: Get a bool shows if this type is an abstract typeIsArray:  Get a bool shows if this type is an arrayIsClass: Get a bool shows if this type is a classIsEnum: Get a bool shows if this type is an enumIsInterface: Get a bool shows if this type is an interfaceIsPublic: Get a bool shows if this type is publicIsSealed: Get a bool shows if this type is sealedIsValueType: Get a bool shows if this type is value type, if not then it’s reference typeAfter
Getting the Typeof the Object through the following code:
    // Create a new instance of the TargetClass
    TargetClass tc = new TargetClass();
    // Get the type of TargetClass
    Type t = tc.GetType();
Then it will be able to call the
Typeclass’smethodsto get the information.
GetField(), GetFields(): Return a FieldInfo Type, for getting the class Member variables’ information.   // Get the Fields from the TargetClass
  FieldInfo[] fis = t.GetFields();
  foreach (FieldInfo fi in fis)
  {
      Debug.Log(fi.Name);
  } 
GetMethod(), GetMethods(): Return a MethodInfo Type, for getting the methods’ information of the class.   // Get the Methods from the TargetClass
  MethodInfo[] mis = t.GetMethods();
  foreach (MethodInfo mi in mis)
  {
      Debug.Log(mi.ReturnType + " " + mi.Name);
  }
GetProperty(), GetProperties(): Return a PropertyInfo Type, for getting the Properties’ information of the class.   // Get the Properties from the TargetClass
  PropertyInfo[] pis = t.GetProperties();
  foreach (PropertyInfo pi in pis)
  {
      Debug.Log(pi.Name);
  }
GetConstructor(), GetConstructors(): Return a ConstructorInfo Type, used for get the class’s Constructors’s information.   // Get all the Constructors of the TargetClass
  ConstructorInfo[] constructorInfos = t.GetConstructors();   
  foreach (ConstructorInfo info in constructorInfos) 
  {
      // Get all the parameters of the constructor
      ParameterInfo[] parameterInfos = info.GetParameters();    
      foreach (ParameterInfo pi in parameterInfos)
      {
          Debug.Log(pi.ParameterType.ToString() + " " + pi.Name + ",");
      }
  }
GetEvent(), GetEvents(): Return a EventInfo Type, for getting the class’s event’s information.   // Get the Events from the TargetClass
  EventInfo[] mis = t.GetEvents();
  foreach (EventInfo mi in mis)
  {
      Debug.Log(mi.EventHandlerType + " " + mi.Name);
  }
GetMember(), GetMembers(): Return a MemberInfo Type, for getting all the members’s information of this class.   // Get the Members from the TargetClass
  MemberInfo[] mis = t.GetMembers();
  foreach (MethodInfo mi in mis)
  {
      Debug.Log(mi.ReturnType + " " + mi.Name);
  }
For calling these member, using Type.InvokeMember(), or other class’s(such as FieldInfo, EvenetInfo, PropertyInfo, etc.) Invoke() functions.
BindingFlags is to Specify flags that control binding and the way in which the search for members and types is conducted by reflection.
Some Common BindingFlags:
BindingFlags.IgnoreCase: Ignore the Case of the member nameBindingFlags.DeclaredOnly: Only Accept the members declared in this class not include inherited memebers.BindingFlags.Instance: Only Accept the Instance membersBindingFlags.Static: Only Accept the Static membersBindingFlags.Public: Only accept the public membersBindingFlags.NonPublic: Only accept the nonpublic membersCode example:
// Here `|` needs to satisify all of these three Flags members will be get fis = typeof(TargetClass).GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
Assembly Class can get Assembly's information, dynamically loads the Assembly, and finds type information in the Assembly and creates Instance of that type.
Assembly ass = Assembly.Load("ClassLibrary");
Type t = ass.GetType("ClassLibrary.NewClass");
object o = Activator.CreateInstance(t);
MethodInfo mi = t.GetMethod("show");
mi.Invoke(o, null);
Assembly assembly = Assembly.LoadFrom("xxx.dll's path");
    Type[] aa = a.GetTypes();
    foreach(Type t in aa)
    {
        if(t.FullName == "a.b.c")
        {
            object o = Activator.CreateInstance(t);
        }
    }
When we are creating the instance in C# we normally will create the object statically.
For example, we have three classes, ClassA, ClassB, ClassC, each of them has a function.
public class ClassA
{
    public void FunctionA()
    {
        Debug.Log("Run Function A");
    }
}
public class ClassB
{
    public void FunctionB()
    {
        Debug.Log("Run Function B");
    }
}
public class ClassC
{
    public void FunctionC()
    {
        Debug.Log("Run Function C");
    }
}
When we want to create certain object through code, we have to use switch case or if statement to make decision and create instance one by one, which is staticly create instance.
public class ReflectionExample : MonoBehaviour
{
    private void Start()
    {
        CreateObject("A");
        CreateObject("B");
        CreateObject("C");
    }
    public static void CreateObject(string className)
    {
        switch (className)
        {
            case "A":
                ClassA a = new ClassA();
                a.FunctionA();
                break;
            case "B":
                ClassB b = new ClassB();
                b.FunctionB();
                break;
            case "C":
                ClassC c= new ClassC();
                c.FunctionC();
                break;
            default:
                break;
        }
    }
}
However, We can use
Reflectionto create ObjectDynamiclybased on the type’s name:
namespace ReflectionDemo
{
    public class ClassA
    {
        public void FunctionA()
        {
            Debug.Log("Run Function A");
        }
    }
    public class ClassB
    {
        public void FunctionB()
        {
            Debug.Log("Run Function B");
        }
    }
    public class ClassC
    {
        public void FunctionC()
        {
            Debug.Log("Run Function C");
        }
    }
    public class ReflectionExample01 : MonoBehaviour
    {
        private void Start()
        {
            DynamicCreateObject("A");
            DynamicCreateObject("B");
            DynamicCreateObject("C");
        }
        public static void DynamicCreateObject(string className)
        {
            var fullPathName = "ReflectionDemo.Class" + className;
            Type type = Type.GetType(fullPathName);
            var obj = Activator.CreateInstance(type);
            var method = obj.GetType().GetMethod("Function" + className);
            if (method != null)
            {
                method.Invoke(obj, null);
            }
        }
    }
}
End –Cheng Gu