View cập nhật dữ liệu (2): nạp chồng, phương thức mở rộng

    7

    Trong bài học này chúng ta sẽ học thêm kỹ thuật nạp chồng phương thức (method overloading) và phương thức mở rộng (extension method) của C#. Chúng ta sẽ vận dụng các kỹ thuật này để tiếp tục cải tiến lớp view cập nhật thông tin.

    Thực hành 1: cải tiến tiếp lớp ViewHelp và BookUpdateView

    Bước 1. Bổ sung phương thức vào lớp ViewHelp

    Bổ sung phương thức sau đây vào cuối class ViewHelp

    /// <summary>
    /// cập nhật giá trị kiểu string. Nếu ấn enter mà không nhập dữ liệu sẽ trả lại giá trị cũ.
    /// </summary>
    /// <param name="label">dòng thông báo</param>
    /// <param name="oldValue">giá trị gốc</param>
    /// <param name="labelColor">màu chữ thông báo</param>
    /// <param name="valueColor">màu chữ dữ liệu</param>
    /// <returns></returns>
    public static string InputString(string label, string oldValue, ConsoleColor labelColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
    {
        Write($"{label}: ", labelColor);
        WriteLine(oldValue, ConsoleColor.Yellow);
        Write("New value >> ", ConsoleColor.Green);
        Console.ForegroundColor = valueColor;
        string newValue = Console.ReadLine();
        return string.IsNullOrEmpty(newValue.Trim()) ? oldValue : newValue;
    }

    Đây là một overload khác của phương thức InputString mà bạn đã tạo từ các bài học trước. Overload này có nhiệm vụ cập nhật giá trị cho một biến kiểu string.

    Phương thức này cập nhật một chuỗi ký tự từ console theo logic sau:

    1. viết dòng thông báo để người dùng nhập dữ liệu (tham số label);
    2. nếu người dùng nhập một xâu ký tự thì xâu mới sẽ được trả lại;
    3. nếu ấn enter luôn (tức là nhập xâu trống) thì trả lại giá trị cũ (tham số oldValue).

    Bước 2. Cải tiến lớp BookUpdateView

    Điều chỉnh phương thức Render để sử dụng các phương thức InputString vừa tạo.

    using Framework;
    using System;
    
    namespace BookMan.ConsoleApp.Views
    {
        using Models;
    
        internal class BookUpdateView
        {
            protected Book Model;
    
            public BookUpdateView(Book model)
            {
                Model = model;
            }
    
            public void Render()
            {
                ViewHelp.WriteLine("UPDATE BOOK INFORMATION", ConsoleColor.Green);
    
                var authors = ViewHelp.InputString("Authors", Model.Authors);
                var title = ViewHelp.InputString("Title", Model.Title);
                var publisher = ViewHelp.InputString("Publisher", Model.Publisher);
                var isbn = ViewHelp.InputString("Isbn", Model.Isbn);
                var tags = ViewHelp.InputString("Tags", Model.Tags);
                var description = ViewHelp.InputString("Description", Model.Description);
                var file = ViewHelp.InputString("File", Model.File);
    
                // TẠM DỪNG ....
            }
        }
    }
    

    Ở bước này chúng ta sử dụng phương thức InputString của lớp ViewHelp để cập nhật dữ liệu cho các trường thuộc kiểu string của lớp Book.

    Bước 3. Dịch và chạy thử với lệnh update

    Kết quả hoạt động của chương trình
    Kết quả hoạt động của chương trình

    Trong phần thực hành trên chúng ta viết thêm một phương thức InputString nữa trong class ViewHelp. Lưu ý rằng, trong class đã có sẵn một phương thức có tên InputString. Đây là nạp chồng phương thức (method overloading).

    Khi sử dụng phương thức có nạp chồng, Intellisense của Visual Studio sẽ hiển thị số lượng các phiên bản nạp chồng và cho phép lựa chọn phiên bản muốn sử dụng.

    Cách Visual Studio hiển thị các phương thức nạp chồng
    Cách Visual Studio hiển thị các phương thức nạp chồng

    Hai phương thức InputString trong lớp ViewHelp có nguyên mẫu (prototype) lần lượt như sau:

    string InputString(string label, ConsoleColor labelColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
    
    string InputString(string label, string oldValue, ConsoleColor labelColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
    

    Như vậy, danh sách tham số của hai phương thức này là khác nhau (trước hết là về số lượng).

    Thực hành: tiếp tục cải tiến lớp BookUpdateView

    Bước 1. Xây dựng lớp Extension

    Thêm file mã nguồn mới Extension.cs trong thư mục Framework. Trong file này định nghĩa một class Extension như sau:

    namespace Framework
    {
        /// <summary>
        /// Mộc số phương thức mở rộng để biến đổi kiểu dữ liệu
        /// </summary>
        public static class Extension
        {
            /// <summary>
            /// Biến đổi từ chuỗi sang số nguyên
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public static int ToInt(this string value)
            {
                return int.Parse(value);
            }
    
            /// <summary>
            /// Biến đổi từ chuỗi sang số nguyên
            /// </summary>
            /// <param name="value"></param>
            /// <param name="i"></param>
            /// <returns></returns>
            public static bool ToInt(this string value, out int i)
            {
                return int.TryParse(value, out i);
            }
    
            /// <summary>
            /// Biến đổi chuỗi Y,y,True, true, sang true
            /// Các chuỗi khác thành false
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public static bool ToBool(this string value)
            {
                var v = value.ToLower();
                if (v == "y" || v == "true") return true;
                return false;
            }
    
            /// <summary>
            /// Biến đổi true/false thành Yes/No hoặc có/không
            /// </summary>
            /// <param name="value"></param>
            /// <param name="format">y/n hoặc c/k</param>
            /// <returns></returns>
            public static string ToString(this bool value, string format)
            {
                if (format == "y/n")
                    return value ? "Yes" : "No";
                if (format == "c/k")
                    return value ? "Có" : "Không";
                return value ? "True" : "False";
            }
        }
    }
    

    Bước 2. Bổ sung thêm phương thức vào lớp ViewHelp

    Bổ sung thêm các overload sau vào lớp ViewHelp:

    public static int InputInt(string label, int oldValue, ConsoleColor labelColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
    {
        Write($"{label}: ", labelColor);
        WriteLine($"{oldValue}", ConsoleColor.Yellow);
        Write("New value >> ", ConsoleColor.Green);
        Console.ForegroundColor = valueColor;
        string str = Console.ReadLine();
        if (string.IsNullOrEmpty(str)) return oldValue;
        if (str.ToInt(out int i)) return i; //sử dụng phương thức mở rộng ToInt
        return oldValue;
    }
    
    public static bool InputBool(string label, bool oldValue, ConsoleColor labelColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
    {
        Write($"{label}: ", labelColor);
        //sử dụng phương thức mở rộng ToString
        WriteLine(oldValue.ToString("y/n"), ConsoleColor.Yellow);
        Write("New value >> ", ConsoleColor.Green);
        Console.ForegroundColor = valueColor;
        string str = Console.ReadLine();
        if (string.IsNullOrEmpty(str)) return oldValue;
        return str.ToBool(); //sử dụng phương thức mở rộng ToBool
    }
    

    Bước 3. Cập nhật phương thức Render của lớp BookUpdateView

    using Framework;
    using System;
    
    namespace BookMan.ConsoleApp.Views
    {
        using Models;
    
        internal class BookUpdateView
        {
            protected Book Model;
    
            public BookUpdateView(Book model)
            {
                Model = model;
            }
    
            public void Render()
            {
                ViewHelp.WriteLine("UPDATE BOOK INFORMATION", ConsoleColor.Green); //sử dụng phương thức static
    
                var authors = ViewHelp.InputString("Authors", Model.Authors);
                var title = ViewHelp.InputString("Title", Model.Title);
                var publisher = ViewHelp.InputString("Publisher", Model.Publisher);
                var isbn = ViewHelp.InputString("Isbn", Model.Isbn);
                var tags = ViewHelp.InputString("Tags", Model.Tags);
                var description = ViewHelp.InputString("Description", Model.Description);
                var file = ViewHelp.InputString("File", Model.File);
                var year = ViewHelp.InputInt("Year", Model.Year);
                var edition = ViewHelp.InputInt("Edition", Model.Edition);
                var rating = ViewHelp.InputInt("Rate", Model.Rating);
                var reading = ViewHelp.InputBool("Reading", Model.Reading);
            }
        }
    }
    

    Bước 4. Dịch và chạy thử chương trình với lệnh update

    Kết quả thực hiện chương trình
    Kết quả thực hiện chương trình

    Trong bước 1 của thực hành trên chúng ta gặp bốn phương thức trong static class Extension:

    public static int ToInt(this string value)
    {
        return int.Parse(value);
    }
    public static bool ToInt(this string value, out int i)
    {
        return int.TryParse(value, out i);
    }
    public static bool ToBool(this string value)
    {
        var v = value.ToLower();
        if (v == "y" || v == "true") return true;
        return false;
    }
    public static string ToString(this bool value, string format)
    {
        if (format == "y/n")
            return value ? "Yes" : "No";
        if (format == "c/k")
            return value ? "Có" : "Không";
        return value ? "True" : "False";
    }
    

    Đây là các phương thức thuộc loại phương thức mở rộng (extension method).

    Kết luận

    Trong bài này chúng ta đã xây dựng được một class nữa để cập nhật thông tin sách. Qua đó, chúng ta làm quen với việc sử dụng phương thức mở rộng và nạp chồng phương thức. Chúng ta cũng sử dụng các công cụ này để cải tiến các lớp view đã xây dựng ở các bài trước giúp loại bỏ tình trạng lặp code giữa các class.

    + Nếu bạn thấy site hữu ích, trước khi rời đi hãy giúp đỡ site bằng một hành động nhỏ để site có thể phát triển và phục vụ bạn tốt hơn.
    + Nếu bạn thấy bài viết hữu ích, hãy giúp chia sẻ tới mọi người.
    + Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần thảo luận cuối trang.
    Cảm ơn bạn!

    Subscribe
    Notify of
    guest
    7 Thảo luận
    Oldest
    Newest
    Inline Feedbacks
    View all comments
    dfdfdk

    this string value có nghĩa là gì vậy ad?

    dfdfdk

    à à bài đấy mình lười đọc quá 🙂

    dfdfdk

    Tức là ở đây có nghĩa là lớp string ko có phương thức ToInt, ToBool … nên mình phải tự định nghĩa phải không?

    LeLinh

    Khi em paste các dòng lệnh liên quan đến “out” như trong code mẫu vào và chạy thì Visual cứ báo lỗi chỗ đó. Ví dụ đoạn:

    if (str.ToInt(out int i)) return i; //sử dụng phương thức mở rộng ToInt
    return oldValue;

    Báo cả chỗ oldValue, chỗ “;”, chỗ “int”,.. luôn ạ. Nó báo phương thức overload này có “invalid arguments” gì đó. Trong khi em chỉ copy và paste thôi @@.

    Tuấn

    Khi gọi hàm có parameter chứa từ khóa out thì mình chỉ gọi (out i) bỏ kiểu dữ liệu.
    Bài của bạn sửa lại là
    if(str.ToInt(out i)) return i;

    Bạn sreach xem lại từ khóa ref và out để xem chi tiết hơn nhé.

    Locnso

    có thể khai báo biến trong tham số out được mà bạn