[C#] 用反射(映射)移除if…else陳述式

[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

Reflection in C# Tutorial

Getting all types that implement an interface with C# 3.5

[.NET]重構之路系列v11 –用責任鏈模式打破討厭的switch case by 91 (跟反射沒什麼關係,不過這是用Design Pattern解決)