using System;
using Microsoft.CSharp.RuntimeBinder;
using System.Reflection;
namespace DynamicLab
{
//定義兩個類別,有一個相同的Property(Name)
//但各有不同的Field(Age vs Score)
class Boo
{
public string Name { get; set; }
public int Age;
}
class Foo
{
public string Name { get; set; }
public int Score;
}
class Program
{
static void Main(string[] args)
{
//分別建立兩個物件
Boo boo = new Boo()
{ Name = "Jeffrey", Age = 25 };
Foo foo = new Foo()
{ Name = "Darkthread", Score = 32767 };
//使用Reflection存取Name屬性及欄位Score
ShowAnythingByReflection(boo);
ShowAnythingByReflection(foo);
//改用dynamic來處理做為對照
ShowAnythingByDynamic(boo);
ShowAnythingByDynamic(foo);
Console.Read();
}
#region Reflection
//Reflection法
static void ShowAnythingByReflection(object obj)
{
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("Name=" + TryGetProperty(obj, "Name"));
try
{
Console.WriteLine("Score=" + TryGetField(obj, "Score"));
}
catch (Exception ex)
{
Console.WriteLine("Error:" + ex.Message);
}
}
//處理Property與處理Field做法不同,故寫成兩個Method
static object TryGetProperty(object obj, string propName)
{
Type objType = obj.GetType();
PropertyInfo pi = objType.GetProperty(propName);
if (pi == null)
throw new ApplicationException(
"Property " + propName + " not found!");
else
return pi.GetValue(obj, null);
}
static object TryGetField(object obj, string fieldName)
{
Type objType = obj.GetType();
FieldInfo fi = objType.GetField(fieldName);
if (fi == null)
throw new ApplicationException(
"Field " + fieldName + " not found!");
else
return fi.GetValue(obj);
}
#endregion
#region Dynamic
//dynamic比較乾脆,直接串上.propName或.fieldName就對了
//編譯一定會過(因為不檢查),若Property或Field不存在,
//則丟出RuntimeBinderException
static void ShowAnythingByDynamic(dynamic dyna)
{
Console.WriteLine("Type: " + dyna.GetType().ToString());
try
{
Console.WriteLine("Name=" + dyna.Name);
}
catch (RuntimeBinderException ex)
{
Console.WriteLine("Error:" + ex.Message);
}
try
{
Console.WriteLine("Score=" + dyna.Score);
}
catch (RuntimeBinderException ex)
{
Console.WriteLine("Error:" + ex.Message);
}
}
#endregion
}
}