C – Sharp là một ngôn ngữ lập trình mạnh mẽ và linh hoạt với nhiều cơ chế giúp tăng tốc độ phát triển và nâng cao hiệu suất thực thi của ứng dụng. Tuy nhiên việc hiểu biết không đầy đủ hoặc đánh giá không đúng khả năng trong một số trường hợp có thể phát sinh các lỗi bất thường. Bài viết này mô tả một sỗ lỗi mà các lập trình viên cần phải khi làm việc với C#
#1. Hiểu sai kiểu mặc định cho các biến chưa khởi tạo
Trong C# kiểu giá trị không được rỗng. Theo định nghĩa, kiểu giá trị luôn có một giá trị cho dù là biến chưa được khởi tạo được gọi là giá trị mặc định của kiểu đó. Hãy xem ví dụ dưới đây:
using System.Drawing; class Program { static Point point; static Pen pen; public static void Main(string[] args) { //Print value True Console.WriteLine(pen == null); //Print value False Console.WriteLine(point == null); } } |
Tại sao point không phải là null? Câu trả lời là point được khai báo là một biến kiểu Point và Point là một kiểu giá trị có giá trị mặc định là (0,0) chứ không phải là null.
Nhiều kiểu giá trị (nhưng không phải tất cả) có thuộc tính IsEmpty dùng để kiểm tra xem biến có bằng giá trị mặc định ứng với kiểu được khai báo hay không.
Console.WriteLine(point.IsEmpty);
#2. Sử dụng phương pháp so sánh chuỗi không đúng hoặc không xác định
Có nhiều cách so sánh chuỗi trong C#. Nhiều lập trình viên sử dụng toán tử ==, tuy nhiên đây là cách không nên sử dụng vì toán tử này không cho phép chỉ định kiểu so sánh, thay vào đó chúng ta nên sử dụng phương thức Equals.
Ví dụ 1: public bool Equals(string value);
Trong ví dụ trên, chúng ta không sử dụng kiểu so sánh StringComparison và vì thế nó hoạt động như toán tử ==, cách so sánh này thực hiện so sánh chuỗi theo từng byte. Trong nhiều trường hợp đây chính là kiểu so sánh cho kết quả mong muốn. Đặc biệt là khi so sánh các chuỗi có giá trị được lập trình như tên tập tin, biến môi trường, thuộc tính,… Nhược điểm duy nhất là không cho chúng ta biết đang thực hiện so sánh theo kiểu nào.
Ví dụ 2: public bool Equals(string value, StringComparison comparisonType);
Cách thực hiện tốt nhất khi so sánh hai chuỗi là sử dụng phương thức Equals với tham số StringComparison. Điều này không chỉ làm cho mã nguồn rõ ràng mà còn khiến chúng ta xác định được loại so sánh sẽ được sử dụng. Đối với StringComparison có một số phương pháp áp dụng như sau:
- Khi so sánh các chuỗi do người dùng nhập hoặc sẽ hiểu thị cho người dùng hãy sử dụng phép so sánh CurrentCulture hoặc CurrentCultureIgnoreCase.
- Khi so sánh các chuỗi có giá trị được lập trình hãy sử dụng phép so sánh thứ tự Ordinal hoặc OrdinalIgnoreCase.
- InvariantCulture và InvariantCultureIgnoreCase ít khi sử dụng vì so sánh theo thứ tự có hiệu quả hơn.
Ngoài phương thức Equals chung, lớp string còn có phương thức Compare cung cấp cho chúng ta nhiều thông tin liên quan tới chuỗi thay vì chỉ so sánh bằng. Phương thức Compare được đề xuất sử dụng thay vì dùng các toán tử như < , <= , > , >= vì các lý do tương tự đã đề cập ở bên trên nhằm ngăn chặn các lổi tiềm ẩn.
#3. Sử dụng tham chiếu như tham trị và ngược lại
Trong lập trình C#, việc quyết định một đối tượng là kiểu tham chiếu hay kiểu tham trị được quyết định bởi lập trình viên định nghĩa đối tượng chứ không phải bởi lập trình viên khởi tạo đối tượng. Nếu không nắm rõ một đối tượng là kiểu tham trị hay loại đối tượng tham chiếu có thể dẫn đến một số kết quả bất ngờ. Hãy xem ví dụ dưới đây:
using System.Drawing; public class Program { public static void Main(string[] args) { //Object Point Point firstPoint = new Point(50, 100); Point secondPoint = firstPoint; secondPoint.X = 200; //X-Coordinate of first point:50 Console.WriteLine(“X-Coordinate of first point:” + firstPoint.X); //X – Coordinate of second point:200 Console.WriteLine(“X-Coordinate of second point:” + secondPoint.X); //Object Pen Pen firstPen = new Pen(Color.Black); Pen secondPen = firstPen; secondPen.Color = Color.Blue; //Color of the first Pen:Color[Blue] Console.WriteLine(“Color of the first Pen:” + firstPen.Color); //Color of the second Pen:Color[Blue] Console.WriteLine(“Color of the second Pen:” + secondPen.Color); } } |
Trong ví dụ trên, cả hai đối tượng Point và Pen đều được khai báo theo cùng một cách nhưng giá trị của firstPoint không thay đổi khi giá trị mới được gán cho secondPoint trong khi đó giá trị của firstPen thay đổi khi một màu mới được gán cho secondPen.
Có kết quả này là bởi mỗi biến firstPoint và secondPoint đều chứa một bản sao của đối tượng Point trong khi cả hai đối tượng firstPen và secondPen đều tham chiếu đến cùng một đối tượng Pen.
Trong C# từ khóa struct được dùng để định nghĩa kiểu giá trị trong khi đó từ khóa class được dùng để định nghĩa kiểu tham chiếu.
public struct Point { //Struct definition } public class Pen { //Class definition } |
Để biết một đối tượng khai báo kiểu struct hay class hãy đặt con trỏ chuột lên đối tượng rồi chọn F12
Khi làm việc với các kiểu đối tượng khác nhau hãy đảm bảo rằng bạn hiểu rõ kiểu của đối tượng đang sử dụng để tránh các vấn đề phát sinh đặc biệt là trong các trường hợp thay đổi giá trị của đối tượng trong chương trình. Chúc các bạn học tốt!
Bộ môn Ứng dụng phần mềm
Trường Cao đẳng FPT Mạng cá cược bóng đá
cơ sở Hà Nội