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:
- viết dòng thông báo để người dùng nhập dữ liệu (tham số label);
- nếu người dùng nhập một xâu ký tự thì xâu mới sẽ được trả lại;
- 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
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.
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
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!
this string value có nghĩa là gì vậy ad?
Đây là cách truyền tham số đặc biệt khi xây dựng phương thức mở rộng. Bạn đọc lại bài học này nhé: https://tuhocict.com/cac-thanh-vien-tinh-static-cua-class/
à à bài đấy mình lười đọc quá 🙂
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?
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 @@.
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é.
có thể khai báo biến trong tham số out được mà bạn
public static bool InputBool(string label, ConsoleColor lableColor = ConsoleColor.Magenta, ConsoleColor valueColor = ConsoleColor.White)
{
Write($”{label} [y/n]: “, lableColor);
Console.ForegroundColor = valueColor;
ConsoleKeyInfo key = Console.ReadKey(); // đọc một kí tự vào biến key
//thêm câu lệnh sau:
Console.WriteLine();// vì dòng trên chưa có new line nên sẽ lỗi trùng dòng cho câu lệnh Write sau. Hiển thị chồng lên nhau.
bool @char = key.KeyChar == ‘y’ || key.KeyChar == ‘Y’ ?
true : false;// chuyển sang kiểu bool dùng biểu thức điều kiện
return @char; // lưu ý cách viết tên biến @char
}