BƯỚC 1: TẠO PROJECT MỚI TRONG VISUAL STUDIO
1.1. Mở Visual Studio
Nhấp đúp vào icon Visual Studio trên Desktop
Hoặc vào Start Menu → Visual Studio 2022
1.2. Tạo Project mới
Hoặc nhấn tổ hợp phím: Ctrl + Shift + N
1.3. Chọn loại Project
Gõ “Console” vào ô tìm kiếm
Chọn Console App (.NET Core) hoặc Console App (.NET Framework)
Nhấn Next
1.4. Đặt tên và cấu hình
Location: Chọn thư mục lưu trữ (ví dụ: D:\CSharp\) Solution name: QuanLySinhVien (giữ nguyên)
Nhấn Next
1.5. Chọn Framework
Chọn .NET 6.0 hoặc .NET 8.0 (LTS – Long Term Support)
Nhấn Create
BƯỚC 2: TẠO CẤU TRÚC THƯ MỤC
2.1. Tạo thư mục Models
Trong Solution Explorer, click chuột phải vào tên Project
Chọn Add → New Folder
Đặt tên:
ModelsNhấn Enter
2.2. Tạo file SinhVien.cs
Click chuột phải vào thư mục Models
Chọn Add → Class
Đặt tên:
SinhVien.csNhấn Add
BƯỚC 3: VIẾT MÃ CHO LỚP SINHVIEN
3.1. Khai báo Namespace và Class
Mở file SinhVien.cs và viết:
using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace QuanLySinhVien.Models { public class SinhVien { // Code sẽ viết ở đây } }
Giải thích:
usingcác namespace cần thiếtnamespace QuanLySinhVien.Models– nhóm các lớp liên quanpublic class SinhVien– khai báo lớp công khai
3.2. Khai báo Fields (Trường dữ liệu)
Thêm vào bên trong class:
{ // === FIELDS (Trường dữ liệu) === private string _maSV; // Mã sinh viên private string _hoTen; // Họ tên private DateTime _ngaySinh; // Ngày sinh private double _diemToan; // Điểm Toán private double _diemLy; // Điểm Lý private double _diemHoa; // Điểm Hóa private static int _tongSo = 0; // Tổng số sinh viên (dùng chung) }
Giải thích:
private– chỉ truy cập được bên trong lớp (tính đóng gói)_(underscore) – quy ước đặt tên cho fieldstatic– biến dùng chung cho tất cả đối tượngDateTime– kiểu dữ liệu ngày tháng
3.3. Khai báo Properties (Thuộc tính)
Thêm vào sau phần Fields:
{ // === FIELDS === private string _maSV; private string _hoTen; private DateTime _ngaySinh; private double _diemToan; private double _diemLy; private double _diemHoa; private static int _tongSo = 0; // === PROPERTIES (Thuộc tính) === // 1. Mã sinh viên - Có kiểm tra rỗng public string MaSV { get { return _maSV; } set { if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Mã sinh viên không được để trống!"); _maSV = value.Trim(); } } // 2. Họ tên - Có kiểm tra rỗng và tự động chuẩn hóa public string HoTen { get { return _hoTen; } set { if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Họ tên không được để trống!"); // Chuẩn hóa: Xóa khoảng trắng thừa string ten = value.Trim(); while (ten.Contains(" ")) ten = ten.Replace(" ", " "); // Viết hoa chữ cái đầu mỗi từ string[] words = ten.Split(' '); for (int i = 0; i < words.Length; i++) { if (!string.IsNullOrEmpty(words[i])) { words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower(); } } _hoTen = string.Join(" ", words); } } // 3. Ngày sinh - Có kiểm tra hợp lệ public DateTime NgaySinh { get { return _ngaySinh; } set { // Kiểm tra ngày sinh không được trong tương lai if (value > DateTime.Now) throw new ArgumentException("Ngày sinh không được trong tương lai!"); // Kiểm tra ngày sinh quá xa (trước năm 1900) if (value < new DateTime(1900, 1, 1)) throw new ArgumentException("Ngày sinh không hợp lệ!"); _ngaySinh = value; } } // 4. Điểm Toán - Có kiểm tra trong khoảng 0-10 public double DiemToan { get { return _diemToan; } set { if (value < 0 || value > 10) throw new ArgumentException("Điểm Toán phải từ 0 đến 10!"); _diemToan = Math.Round(value, 1); // Làm tròn 1 chữ số thập phân } } // 5. Điểm Lý - Có kiểm tra trong khoảng 0-10 public double DiemLy { get { return _diemLy; } set { if (value < 0 || value > 10) throw new ArgumentException("Điểm Lý phải từ 0 đến 10!"); _diemLy = Math.Round(value, 1); } } // 6. Điểm Hóa - Có kiểm tra trong khoảng 0-10 public double DiemHoa { get { return _diemHoa; } set { if (value < 0 || value > 10) throw new ArgumentException("Điểm Hóa phải từ 0 đến 10!"); _diemHoa = Math.Round(value, 1); } } // 7. Tổng số sinh viên (Read-only - chỉ đọc) public static int TongSo { get { return _tongSo; } } }
Giải thích từng Property:
| Property | Ý nghĩa | Logic kiểm tra |
|---|---|---|
MaSV | Mã sinh viên | Không được rỗng, tự động Trim |
HoTen | Họ tên | Không rỗng + Chuẩn hóa (xóa khoảng trắng, viết hoa đầu từ) |
NgaySinh | Ngày sinh | Không trong tương lai, không trước 1900 |
DiemToan | Điểm Toán | Từ 0 đến 10, làm tròn 1 số |
DiemLy | Điểm Lý | Từ 0 đến 10, làm tròn 1 số |
DiemHoa | Điểm Hóa | Từ 0 đến 10, làm tròn 1 số |
TongSo | Tổng số SV | Chỉ đọc (Read-only), dùng chung (static) |
3.4. Khai báo Computed Properties (Thuộc tính tính toán)
{ // ... Fields và Properties ở trên ... // === COMPUTED PROPERTIES (Thuộc tính tính toán) === // Điểm trung bình - Tự động tính từ 3 môn public double DiemTrungBinh { get { return Math.Round((_diemToan + _diemLy + _diemHoa) / 3.0, 2); } } // Xếp loại - Tự động phân loại dựa trên điểm TB public string XepLoai { get { double dtb = DiemTrungBinh; if (dtb >= 9.0) return "Xuất sắc"; if (dtb >= 8.0) return "Giỏi"; if (dtb >= 6.5) return "Khá"; if (dtb >= 5.0) return "Trung bình"; return "Yếu"; } } // Tuổi - Tự động tính từ ngày sinh public int Tuoi { get { DateTime today = DateTime.Today; int age = today.Year - _ngaySinh.Year; // Nếu chưa qua sinh nhật trong năm nay thì trừ 1 if (_ngaySinh.Date > today.AddYears(-age)) age--; return age; } } }
Giải thích:
Computed Property – Thuộc tính không lưu trữ, tự tính toán khi đọc
DiemTrungBinh– Tính trung bình 3 mônXepLoai– Phân loại theo thang điểmTuoi– Tính từ ngày sinh
3.5. Khai báo Constructors (Phương thức khởi tạo)
{ // ... Fields, Properties, Computed Properties ở trên ... // === CONSTRUCTORS (Phương thức khởi tạo) === // Constructor 1: Không tham số (Default) public SinhVien() { _maSV = "SV" + (_tongSo + 1).ToString("D3"); _hoTen = "Chưa xác định"; _ngaySinh = new DateTime(2000, 1, 1); _diemToan = 0; _diemLy = 0; _diemHoa = 0; _tongSo++; // Tăng số lượng sinh viên } // Constructor 2: Có tham số đầy đủ public SinhVien(string maSV, string hoTen, DateTime ngaySinh, double diemToan, double diemLy, double diemHoa) { // Sử dụng Properties để có kiểm tra logic MaSV = maSV; HoTen = hoTen; NgaySinh = ngaySinh; DiemToan = diemToan; DiemLy = diemLy; DiemHoa = diemHoa; _tongSo++; // Tăng số lượng sinh viên } // Constructor 3: Chỉ có mã và tên (các giá trị khác mặc định) public SinhVien(string maSV, string hoTen) : this() { MaSV = maSV; HoTen = hoTen; // Ngày sinh, điểm giữ nguyên mặc định } }
Giải thích:
| Constructor | Cách dùng | Mục đích |
|---|---|---|
SinhVien() | new SinhVien() | Tạo SV mới với giá trị mặc định |
SinhVien(ma, ten, ngay, toan, ly, hoa) | new SinhVien("SV001", "A", ...) | Tạo SV với đầy đủ thông tin |
SinhVien(ma, ten) | new SinhVien("SV001", "A") | Tạo SV với mã và tên, các giá trị khác mặc định |
3.6. Khai báo Methods (Phương thức)
{ // ... Fields, Properties, Constructors ở trên ... // === METHODS (Phương thức) === // 1. Hiển thị thông tin sinh viên public void HienThi() { Console.WriteLine("═══════════════════════════════════════"); Console.WriteLine($" Mã sinh viên : {_maSV}"); Console.WriteLine($" Họ và tên : {_hoTen}"); Console.WriteLine($" Ngày sinh : {_ngaySinh:dd/MM/yyyy}"); Console.WriteLine($" Tuổi : {Tuoi}"); Console.WriteLine($" Điểm Toán : {_diemToan:F1}"); Console.WriteLine($" Điểm Lý : {_diemLy:F1}"); Console.WriteLine($" Điểm Hóa : {_diemHoa:F1}"); Console.WriteLine($" Điểm TB : {DiemTrungBinh:F2}"); Console.WriteLine($" Xếp loại : {XepLoai}"); Console.WriteLine("═══════════════════════════════════════"); } // 2. Hiển thị tóm tắt (1 dòng) public string HienThiTomTat() { return $"{_maSV,-10} | {_hoTen,-25} | {DiemTrungBinh,6:F2} | {XepLoai,-12}"; } // 3. Kiểm tra sinh viên có đạt hay không public bool IsDat() { return DiemTrungBinh >= 5.0 && _diemToan >= 4.0 && _diemLy >= 4.0 && _diemHoa >= 4.0; } // 4. Kiểm tra sinh viên có giỏi hay không public bool IsGioi() { return DiemTrungBinh >= 8.0; } // 5. So sánh điểm TB với sinh viên khác public int SoSanhDiem(SinhVien other) { if (other == null) return 1; return this.DiemTrungBinh.CompareTo(other.DiemTrungBinh); } // 6. Override ToString() - hiển thị thông tin dạng chuỗi public override string ToString() { return $"{_maSV} - {_hoTen} - {DiemTrungBinh:F2} - {XepLoai}"; } }
Giải thích các phương thức:
| Method | Ý nghĩa |
|---|---|
HienThi() | In đầy đủ thông tin ra màn hình |
HienThiTomTat() | Trả về 1 dòng tóm tắt |
IsDat() | Kiểm tra đạt hay không (TB>=5, không môn nào dưới 4) |
IsGioi() | Kiểm tra giỏi (TB>=8) |
SoSanhDiem() | So sánh điểm với SV khác |
ToString() | Ghi đè để hiển thị dạng chuỗi |
BƯỚC 4: VIẾT CHƯƠNG TRÌNH KIỂM TRA (TEST)
Mở file Program.cs và viết code test:
using System.Collections.Generic; using QuanLySinhVien.Models; namespace QuanLySinhVien { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; Console.WriteLine("===== KIỂM TRA LỚP SINH VIÊN =====\n"); // 1. Tạo đối tượng bằng Constructor mặc định Console.WriteLine("1. Constructor mặc định:"); SinhVien sv1 = new SinhVien(); sv1.HienThi(); // 2. Tạo đối tượng bằng Constructor có tham số Console.WriteLine("\n2. Constructor có tham số:"); SinhVien sv2 = new SinhVien( "SV001", "nguyễn văn a", new DateTime(2005, 5, 10), 9.5, 8.5, 9.0 ); sv2.HienThi(); // 3. Tạo đối tượng với constructor 2 tham số Console.WriteLine("\n3. Constructor 2 tham số:"); SinhVien sv3 = new SinhVien("SV002", "Trần Thị B"); sv3.HienThi(); // 4. Kiểm tra tính năng tự động tăng mã Console.WriteLine("\n4. Tự động tăng mã SV:"); SinhVien sv4 = new SinhVien(); Console.WriteLine($"Mã SV tự động: {sv4.MaSV}"); // 5. Kiểm tra static property Console.WriteLine($"\n5. Tổng số sinh viên: {SinhVien.TongSo}"); // 6. Kiểm tra validation Console.WriteLine("\n6. Kiểm tra validation:"); try { SinhVien sv5 = new SinhVien("", "Hợp lệ", DateTime.Now, 9, 8, 7); } catch (Exception ex) { Console.WriteLine($"Lỗi: {ex.Message}"); } try { SinhVien sv6 = new SinhVien("SV003", "Hợp lệ", DateTime.Now.AddDays(1), 9, 8, 7); } catch (Exception ex) { Console.WriteLine($"Lỗi: {ex.Message}"); } try { SinhVien sv7 = new SinhVien("SV004", "Hợp lệ", new DateTime(2000, 1, 1), 11, 8, 7); } catch (Exception ex) { Console.WriteLine($"Lỗi: {ex.Message}"); } // 7. Kiểm tra xếp loại Console.WriteLine("\n7. Kiểm tra xếp loại:"); TestXepLoai(9.5, 9.0, 9.5); // Xuất sắc TestXepLoai(8.5, 8.0, 8.5); // Giỏi TestXepLoai(7.0, 7.5, 6.5); // Khá TestXepLoai(5.5, 5.0, 6.0); // Trung bình TestXepLoai(4.0, 4.5, 3.5); // Yếu // 8. Kiểm tra ToString() Console.WriteLine("\n8. Phương thức ToString():"); Console.WriteLine(sv2.ToString()); Console.WriteLine("\nNhấn phím bất kỳ để kết thúc..."); Console.ReadKey(); } static void TestXepLoai(double toan, double ly, double hoa) { SinhVien sv = new SinhVien("TEST", "Test", new DateTime(2000, 1, 1), toan, ly, hoa); Console.WriteLine($"Điểm TB: {sv.DiemTrungBinh:F2} - Xếp loại: {sv.XepLoai}"); } } }
BƯỚC 5: CHẠY CHƯƠNG TRÌNH VÀ KIỂM TRA
5.1. Build Project
Nhấn
Ctrl + Shift + Bđể biên dịchHoặc vào menu Build → Build Solution
5.2. Chạy chương trình
Nhấn
F5để chạy (Debug mode)Hoặc
Ctrl + F5để chạy không debug
5.3. Kết quả dự kiến
1. Constructor mặc định: ═══════════════════════════════════════ Mã sinh viên : SV001 Họ và tên : Chưa xác định Ngày sinh : 01/01/2000 Tuổi : 24 Điểm Toán : 0.0 Điểm Lý : 0.0 Điểm Hóa : 0.0 Điểm TB : 0.00 Xếp loại : Yếu ═══════════════════════════════════════ 2. Constructor có tham số: ═══════════════════════════════════════ Mã sinh viên : SV001 Họ và tên : Nguyễn Văn A Ngày sinh : 10/05/2005 Tuổi : 19 Điểm Toán : 9.5 Điểm Lý : 8.5 Điểm Hóa : 9.0 Điểm TB : 9.00 Xếp loại : Xuất sắc ═══════════════════════════════════════ ... (các kết quả khác)