[C#] 用反射(映射)移除if…else陳述式
昨晚睡覺前不知怎的,覺得有時候我們用的if…else…或switch陳述式
應該可以改成Reflection動態叫用Method的方式來移除一條一條的if判斷
趕緊趁還沒忘掉前,做個簡單範例記錄下來
一般寫法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DayOfWeek today = DateTime.Now.DayOfWeek;
switch (today.ToString())
{
case "Monday":
Console.WriteLine("今天是星期一");
break;
case "Tuesday":
Console.WriteLine("今天是星期二");
break;
case "Wednesday":
Console.WriteLine("今天是星期三");
break;
case "Thursday":
Console.WriteLine("今天是星期四");
break;
case "Friday":
Console.WriteLine("今天是星期五");
break;
case "Saturday":
Console.WriteLine("今天是星期六");
break;
case "Sunday":
Console.WriteLine("今天是星期日");
break;
}
Console.ReadKey();//暫停畫面
}
}
}
改用Reflection移除switch判斷:
Step 1.新增一個類別MySchedule.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class MySchedule
{
public MySchedule() { }
public string actionOnMonday()
{
return "今天是星期一";
}
public string actionOnTuesday()
{
return "今天是星期二";
}
public string actionOnWednesday()
{
return "今天是星期三";
}
public string actionOnThursday()
{
return "今天是星期四";
}
public string actionOnFriday()
{
return "今天是星期五";
}
public string actionOnSaturday()
{
return "今天是星期六";
}
public string actionOnSunday()
{
return "今天是星期日";
}
}
}
Step 2. 主程式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DayOfWeek today = DateTime.Now.DayOfWeek;//假設這是使用者輸入的訊息
//要玩反射,都從Type開始寫...
Type t = Type.GetType("ConsoleApplication1.MySchedule");//或typeof(MySchedule);
//拼接要執行method的名稱
string methodName = "actionOn" + today.ToString();
//第一種寫法:用MethodInfo去invoke
MethodInfo mInfo = t.GetMethod(methodName);
object result = null;//儲存invoke的回傳結果
result = mInfo.Invoke(Activator.CreateInstance(t), null);
Console.WriteLine(result);//輸出結果
//第二種寫法:用Type去invokeMember
result = t.InvokeMember(methodName, BindingFlags.InvokeMethod, null, Activator.CreateInstance(t), null);
Console.WriteLine(result);//輸出結果
Console.ReadKey();//暫停畫面
}
}
}
以上的解法
都是同一類別下,調用的方法由使用者輸入字串決定
由於類別名稱和方法名稱都是字串
所以應該也可以做到使用者輸入不同的字串,動態調用不同物件、不同方法
只是如此一來,當初命名類別和方法時,就得考慮使用者會輸入什麼字串了
其他文章:
C#: Using Reflection to Instantiate a Generic Class in .Net
Getting all types that implement an interface with C# 3.5
[.NET]重構之路系列v11 –用責任鏈模式打破討厭的switch case by 91 (跟反射沒什麼關係,不過這是用Design Pattern解決)