Reflection and LateBinding


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ReflectionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Reflection入門
            //ReflectionBasic();

            //LateBinding
            LateBindingDemo();

            Console.ReadLine();
        }

        #region Reflection入門

        public static void ReflectionBasic()
        {
            /*
            這種方式是一個static method,比較適用於呼叫資料都保存在 XML 檔案中
            Type.GetType("namespace的名稱.Class的名稱")
            https://dotblogs.com.tw/regionbbs/2011/02/09/invoke_generic_methods
            */
            Type t1 = Type.GetType("ReflectionDemo.Gamer");

            /*
             typeof(Class的名稱)
             */
            //Type t1 = typeof(Gamer);

            /*
             第三種方式
             */
            //Gamer gamerA = new Gamer();
            //Type t1 = gamerA.GetType();

            if (t1 != null)
            {
                //列印出class裡面的所有Method
                Console.WriteLine("完整名稱:" + t1.FullName);
                Console.WriteLine("Namespace名稱:" + t1.Namespace);
                Console.WriteLine("Class名稱:" + t1.Name);
                Console.WriteLine("所有Method如下:");
                MethodInfo[] MI = t1.GetMethods();
                foreach (MethodInfo obj in MI)
                {
                    Console.WriteLine("回傳型態:" + obj.ReturnType.Name + " , Method名稱:" + obj.Name);

                }

                //列印出class裡面的所有Property
                Console.WriteLine("");
                Console.WriteLine("所有Property如下:");
                PropertyInfo[] PI = t1.GetProperties();
                foreach (PropertyInfo obj in PI)
                {
                    Console.WriteLine("型態:" + obj.PropertyType.Name + " , Field名稱:" + obj.Name);
                }
                Console.WriteLine("列印特定Property如下:");
                //列印特定Property
                Console.WriteLine("型態:" + t1.GetProperty("Name").PropertyType.Name + " , Field名稱:" + t1.GetProperty("Name").Name);

                //列印出class裡面的所有Constructor
                Console.WriteLine("");
                Console.WriteLine("所有Constructor如下:");
                ConstructorInfo[] CI = t1.GetConstructors();
                foreach (ConstructorInfo obj in CI)
                {
                    Console.WriteLine(obj.ToString());
                }
            }
        }

        #endregion

        #region LateBinding
        public static void LateBindingDemo()
        {
            #region 載入 Assembly (DLL or Exe)
            #region 方法一:載入目前的 Assembly (DLL or Exe)
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            #endregion
            #region 方法二:載入指定的 Assembly (DLL or Exe)
            // 執行以下這行之前,必須在當前的專案加入參考,並且建置之後,即可載入 \bin\debug\ 底下的 dll 或 exe
            //Assembly executingAssembly = Assembly.LoadFrom("ClassLibrary1.dll");
            #endregion
            #endregion

            Type gamerType = executingAssembly.GetType("ReflectionDemo.Gamer");

            #region CreateInstance
            // 其實就像是 Gamer a = new Gamer(); 一樣,所以一樣也會觸發 Constructor
            #region 呼叫沒有參數的 Constructor
            object gamerInstance = Activator.CreateInstance(gamerType);
            #endregion
            #region 呼叫有參數的 Constructor
            //object[] Parameters = new object[2];
            //Parameters[0] = "楊";
            //Parameters[1] = 100;
            //object gamerInstance = Activator.CreateInstance(gamerType, Parameters);
            #endregion
            #endregion

            Console.WriteLine("****** 呼叫 Gamer 這個 Class 裡面的 public override string ToString() ******");
            MethodInfo toStringMethodInfo = gamerType.GetMethod("ToString");//呼叫 Gamer 這個 Class 裡面的 public override string ToString()
            if (toStringMethodInfo != null)
            {
                //6.5.
                // TypeObject.GetMethod(string MethodName) can get the MethodInfo
                // by the string value of MethodName.
                string gamerToString = (string)toStringMethodInfo.Invoke(gamerInstance, null);
                Console.WriteLine($"呼叫 public override string ToString() ---> {gamerToString}");


                // 6.6.
                // TypeObject.GetProperty(string PropertyName) can get the PropertyInfo
                // by using string value of PropertyName.
                PropertyInfo namePropertyInfo = gamerType.GetProperty("Name");
                if (namePropertyInfo != null)
                {
                    MethodInfo namePropertySetValue = namePropertyInfo.SetMethod;
                    MethodInfo namePropertyGetValue = namePropertyInfo.GetMethod;

                    object[] namePropertySetMethodParameters = new object[1];
                    namePropertySetMethodParameters[0] = "林書豪";
                    namePropertySetValue.Invoke(gamerInstance, namePropertySetMethodParameters);

                    object name = namePropertyGetValue.Invoke(gamerInstance, null);


                    PropertyInfo agePropertyInfo = gamerType.GetProperty("Age");
                    if (agePropertyInfo != null)
                    {
                        MethodInfo agePropertySetValue = agePropertyInfo.SetMethod;
                        MethodInfo agePropertyGetValue = agePropertyInfo.GetMethod;

                        object[] agePropertySetMethodParameters = new object[1];
                        agePropertySetMethodParameters[0] = 20;
                        agePropertySetValue.Invoke(gamerInstance, agePropertySetMethodParameters);

                        object age = agePropertyGetValue.Invoke(gamerInstance, null);
                        Console.WriteLine("");
                        Console.WriteLine("****** 使用Property之後 ******");
                        Console.WriteLine($"玩家Name: {name} , 年齡:{age}");
                    }
                }

                // 6.9.
                // TypeObject.GetMethod(string MethodName) can get the MethodInfo
                // by the string value of MethodName.
                Console.WriteLine("");
                Console.WriteLine("****** 呼叫 Gamer 這個 Class 裡面的 public string PrintName() ******");
                MethodInfo printNameMethodInfo = gamerType.GetMethod("PrintName");
                if (printNameMethodInfo != null)
                {
                    Console.WriteLine(printNameMethodInfo.Invoke(gamerInstance, null));
                }

                // 6.10.
                // TypeObject.GetMethod(string MethodName) can get the MethodInfo
                // by the string value of MethodName.
                Console.WriteLine("");
                Console.WriteLine("****** 呼叫 Gamer 這個 Class 裡面的 public string PrintAge() ******");
                MethodInfo printGameAgeMethodInfo = gamerType.GetMethod("PrintAge");
                if (printGameAgeMethodInfo != null)
                {
                    Console.WriteLine(printGameAgeMethodInfo.Invoke(gamerInstance, null));
                }

                // 6.11.
                // TypeObject.GetMethod(string MethodName) can get the MethodInfo
                // by the string value of MethodName.
                Console.WriteLine("");
                Console.WriteLine("****** 呼叫 Gamer 這個 Class 裡面的 public override string ToString() ******");
                gamerToString = (string)toStringMethodInfo.Invoke(gamerInstance, null);
                Console.WriteLine($"呼叫 public override string ToString() ---> {gamerToString}");

                // 6.12.
                // 6.12.1.
                // TypeObject.GetMethod(string MethodName) can get the MethodInfo
                // by the string value of MethodName.
                Console.WriteLine("");
                Console.WriteLine("****** public string SetNameAndAge(string name, int age) ******");
                MethodInfo setNameAndGameAgeMethodInfo = gamerType.GetMethod("SetNameAndAge");

                object gamerStr = null;
                object[] methodParameters = new object[2];
                methodParameters[0] = "葉靜香"; //Name
                methodParameters[1] = 30;     //Age
                // 6.12.3.
                // MethodInfoObject.Invoke(object InstanceObject, object[] methodParametersObjectArr)
                // invoke the method and get the return value.
                if (setNameAndGameAgeMethodInfo == null)
                {
                    return;
                }
                else
                {
                    gamerStr = (string)setNameAndGameAgeMethodInfo.Invoke(gamerInstance, methodParameters);
                }

                Console.WriteLine($"呼叫 public string SetNameAndAge(string name, int age) ---> {gamerStr}");
            }
            #endregion
        }
    }
    public class Gamer
    {
        #region Field

        private string _Name;

        #endregion

        #region Property

        public int Age { set; get; }

        public string Name
        {
            set { this._Name = value; }
            get { return this._Name; }
        }

        #endregion

        #region Constructor

        public Gamer()
        {
            _Name = string.Empty;
            Age = 18;
        }

        public Gamer(string name, int age)
        {
            this._Name = name;
            this.Age = age;
        }
        #endregion

        #region Method/Function

        public static void Calc<T>(T para1, T pars2)
        {
            Console.WriteLine(Convert.ToInt32(para1) + Convert.ToInt32(pars2));
        }

        public override string ToString()
        {
            return "玩家的名字為:" + Name + " , 年齡為:" + Age;
        }

        public string PrintName()
        {
            return Name;
        }

        public int PrintAge()
        {
            return Age;
        }

        public string SetNameAndAge(string name, int age)
        {
            this._Name = name;
            this.Age = age;
            return "玩家的名字為:" + _Name + " , 年齡為:" + Age;
        }
        #endregion
    }
}

results matching ""

    No results matching ""