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