字串陣列解析小品集 (6) Extension Method With Func and Generic

改變一個想法,來改造 字串陣列解析小品集 (4) 外部實作法 (Extension Method) ,讓擴充方法能夠更靈活。而且這次會做一個小改變就是把方法作業進行的型別從原本的最終資料的型別 (DataForTextFile1 或  DataForTextFile2) 換成使用 string[]

 

字串陣列解析小品集 (4) 外部實作法 (Extension Method) 中,我們談到了用擴充方法來實作解析的內容,將解析的實作程式碼整個就擺在擴充方法的內部。但如果情境上會出現『即使是同一份文字檔,都可能因為在不同的程式功能中會有不同的解析方式』,那前述 (4) 的方式可能就不太適合。

資料型別和 (4) 相同,是個完全乾淨只具有屬性的類別:

    public class DataForTextFile1
    {
        public int Index { get; set; }

        public string English { get; set; }

        public string Chinese { get; set; }

    }

    public class DataForTextFile2
    {

        public int Index { get; set; }

        public string Person { get; set; }

        public DayOfWeek WeekDay { get; set; }

        public string Activity { get; set; }
    }

Extension Method 的部分改成以下形式,讓解析的作業改變成以 Func<string[],T> 的方式傳入,並且在內部判斷字串陣列是否符合屬性長度的需求:
 

    public static class Parser
    {

        public static T Parse<T>(this string[] items, Func<string[], T> parser)
        {
            if (items == null)
            { throw new ArgumentNullException(); }
            var propertites = typeof(T).GetProperties();
            if (items.Count() < propertites.Count ()  )
            { throw new ArgumentException(); }
            return parser.Invoke(items);
        }
    }

最後是呼叫端的實作,把解析的作業用 lambda 表示式傳給 Extension Method:
 

    class Program
    {
        static void Main(string[] args)
        {
            ProcessTextFile1();
            Console.WriteLine();
            Console.WriteLine("**********************************");
            Console.WriteLine();
            ProcessTextFile2();
            Console.ReadLine();
        }

        static void ProcessTextFile1()
        {
            var lines = File.ReadAllLines("TextFile1.txt");
            List<DataForTextFile1> list = new List<DataForTextFile1>();
            foreach (var line in lines)
            {
                string[] items = line.Split(',');
                if (items != null)
                {
                    var obj = items.Parse((x) =>
                    {
                        DataForTextFile1 y = new DataForTextFile1();
                        y.Index = int.Parse(x[0]);
                        y.English = x[1];
                        y.Chinese = x[2];
                        return y;
                    });
                    list.Add(obj);
                }
            }

            // 顯示結果
            foreach (var item in list)
            {
                Console.WriteLine(item.Index.ToString());
                Console.WriteLine(item.English);
                Console.WriteLine(item.Chinese);
                Console.WriteLine("---------------------");
            }
        }


        static void ProcessTextFile2()
        {
            var lines = File.ReadAllLines("TextFile2.txt");
            List<DataForTextFile2> list = new List<DataForTextFile2>();
            foreach (var line in lines)
            {
                string[] items = line.Split(',');
                if (items != null)
                {
                    var obj = items.Parse((x) =>
                    {
                        DataForTextFile2 y = new DataForTextFile2();
                        y.Index = int.Parse(x[0]);
                        y.Person = items[1];
                        y.WeekDay = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), items[2]);
                        y.Activity = items[3];
                        return y;
                    });
                    list.Add(obj);
                }
            }

            // 顯示結果
            foreach (var item in list)
            {
                Console.WriteLine(item.Index.ToString());
                Console.WriteLine(item.Person);
                Console.WriteLine(item.WeekDay);
                Console.WriteLine(item.Activity);
                Console.WriteLine("---------------------");
            }
        }
    }