8 lỗi phổ biến trong khi lập trình C#
Trong khi làm việc với những coder trẻ tuổi, tôi đã phải nhắc những lỗi cơ bản bị gặp nhiều lần. Đó là các lỗi phổ biến và rất dễ nhớ. Tuy nhiên nếu bạn là 1 coder không để ý đến chúng, chúng có thể là nguyên nhân của rất nhiều các vấn đề ảnh hưởng đến chất lượng phần mềm của bạn. Vì thế tôi quyết định liệt kê ra 8 lỗi căn bản khi viết code C#:
1. Nối chuỗi thay vì sử dụng StringBuilder
Việc nối chuỗi là một thao tác lặp đi lặp lại rất nhiều lần trong việc lập trình của bạn. Khi muốn thêm cái gì đó vào một chuỗi có sẵn, một địa chỉ mới trong bộ nhớ sẽ được cấp phát. Chuỗi có sẵn sẽ được sao chép sang vị trí mới đồng thời được thêm phần mới vào. Điều này là không hiệu quả cho hiệu suất. Chúng ta có giải pháp khác là sử dụng StringBuilder sẽ giữ nguyên vị trí bộ nhớ mà không thực hiện hành động sao chép. Theo cách này sẽ tăng hiệu suất rất nhiều đặc biệt khi bạn thực hiện hàng trăm thao tác append.
//INCORRECT
List values = new List(){"This ","is ","Sparta ","!"};
string outputValue = string.Empty;
foreach (var value in values)
{
outputValue += value;
}
//CORRECT
StringBuilder outputValueBuilder = new StringBuilder();
foreach (var value in values)
{
outputValueBuilder.Append(value);
}
2. LINQ – Sử dụng ‘Where’ với ‘First’ thay vì FirstOrDefault
Rất nhiều coder lấy ra 1 tập các phần tử bằng cách sử dụng mệnh đề Where và trả về đối tượng đầu tiên trong tập đó. Điều này không nên vì phương thức ‘First()’ cũng có tác dụng tương tự như Where. Hơn nữa, không phải lúc nào cũng có dữ liệu, và nếu sử dụng “First()” thì sẽ gặp Exception nếu không có dữ liệu. Vì thế tốt hơn chúng ta dùng FirstOrDefault(). Khi sử dụng FirstOrDefault() nếu không có giá trị nào được tìm thấy, nó sẽ trả về giá trị mặc định của kiểu dữ liệu đó thay vì throw ra Exception
//INCORRECT
List numbers = new List(){1,4,5,9,11,15,20,21,25,34,55};
return numbers.Where(x => Fibonacci.IsInFibonacciSequence(x)).First();
//PARTLY CORRECT
return numbers.First(x => Fibonacci.IsInFibonacciSequence(x));
//CORRECT
return numbers.FirstOrDefault(x => Fibonacci.IsInFibonacciSequence(x));
3. Ép kiểu sử dụng ‘(T)’ thay vì ‘as (T)’
Đây là lỗi phổ biến của các developer sử dụng cách ép kiểu ‘(T)’ thay vì ‘as (T)’. Và thưowngf thì không có tác động tiêu cực nào nhưng trong trường hợp không thể ép được thì ép kiểu (T) sẽ throw ra InvalidCastException còn toán tử “as” sẽ trả về null nếu không thể ép kiểu
//INCORRECT
var woman = (Woman)person;
//CORRECT
var woman = person as Woman;
.4. Không sử dụng Mapping khi rewrite các Properties
Có rất nhiều các thư viện mạnh mẽ dùng cho việc mapping trong C# (ví dụ như AutoMapper). Chỉ cần vài dòng có là bạn có thể mapping giữa 2 đối tượng với nhau ngay cả khi tên thuộc tính không giống nhau các bạn cũng có thể thêm một số logic để chúng có thể map dữ liệu ngon lành
5. Throw exception không đúng cách.
Lập trình viên C# thường quên rằng khi họ throw một exception sử dụng “throw ex” họ sẽ mất stack trace. Nó làm cho việc debug khó khăn hơn và khó tiếp cận message lỗi hơn. Đơn giản chỉ cần “throw” là được, không dữ liệu Exception nào bị mất và toàn bộ Excpetion sẽ được trả về dễ dàng.
//INCORRECT
try
{
//some code that can throw exception [...]
}
catch (Exception ex)
{
//some exception logic [...]
throw ex;
}
//CORRECT
try
{
//some code that can throw exception [...]
}
catch (Exception ex)
{
//some exception logic [...]
throw;
}
6. Không sử dụng “using” cho việc hủy đối tượng
Nhiều C# developer không biết việc sử dụng từ khóa “using” không chỉ để thêm mới 1 thư viện ở đầu file .cs mà còn để hủy đối tượng sau khi thực hiện tác vụ, luôn sử dụng lệnh “using” để chắc chắn rằng đối tượng đó đã được hủy
//the below code:
using(SomeDisposableClass someDisposableObject = new SomeDisposableClass())
{
someDisposableObject.DoTheJob();
}
//does the same as:
SomeDisposableClass someDisposableObject = new SomeDisposableClass();
try
{
someDisposableObject.DoTheJob();
}
finally
{
someDisposableObject.Dispose();
}
7. Sử dụng “foreach” cho tất cả mọi thứ ngoài Collection
Hãy nhớ là nếu bạn muốn lặp qua bất cứ thứ gì không phải Colleciton ( ví dụ là 1 Array), sử dụng vòng lặp “for” sẽ hiệu quả hơn nhiều so với sử dụng “foreach”. Nguyên nhân là cả 2 loại vòng lặp này được hiểu và biên dịch theo cách khác nhau. Vì “foreach” khi biên dịch ra JIT (Just In Time) code có nhiều thao tác hơn và khai báo nhiều biến hơn so với vòng “for” như thế giảm performance của hệ thống.
8. Đọc, ghi dữ liệu với DB nhiều hơn 1 lời gọi
Đây là lỗi rất phổ biến, đặc biệt là các junior developer và đặc biệt là sử dụng ORM như Entity Framework. Tất cả các lời gọi DB đều chiếm một khoảng thời gian nhất định nên việc giảm số lượng tối thiểu lời gọi vào DB là điều rất quan trọng. Có nhiều cách để làm việc đó:
- Sử dụng fetching (Eager Loading)
- Sử dụng Transaction
- Trong trường hợp logic phức tạp nên sử dụng trong Store Procedure.
Trên đây là một trong số hàng trăm lỗi phổ biến của các C# developer. Nếu bạn biết hoặc thấy có ý kiến bổ sung cho lỗi nào vui lòng chia sẻ ở comment phía dưới.
Tác giả: Bạch Ngọc Toàn
Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.
Bài viết liên quan
Sử dụng kiểu tập hợp (Enum)
Enum (viết tắt của Enumeration) trong C# là một kiểu dữ liệu đặc biệt cho phép bạn định nghĩa một tập hợp các hằng số có tên
Đọc thêmTính đóng gói (Encapsulation) và best practices trong OOP
(Tính đóng gói) là một trong những nguyên tắc cơ bản của lập trình hướng đối tượng (OOP).
Đọc thêmTính trừu tượng - Abstract classes and interfaces
Tính trừu tượng (Abstraction) trong OOP là kỹ thuật ẩn đi các chi tiết triển khai và chỉ hiển thị cho người dùng những chức năng cần thiết.
Đọc thêmTính chất kế thừa (Inheritance) và đa hình (polymorphism)
Kế thừa là cơ chế cho phép một lớp (class) kế thừa các thuộc tính và phương thức từ một lớp khác.
Đọc thêmCách debug ứng dụng C#
Hướng dẫn cách debug chương trình C# trong Visual Studio và Visual Studio Code
Đọc thêmTìm hiểu về các loại Collection trong C#
Trong C#, collections là các cấu trúc dữ liệu được sử dụng để lưu trữ và quản lý các nhóm đối tượng. C# cung cấp nhiều loại collections khác nhau để phù hợp với các yêu cầu cụ thể của lập trình viên
Đọc thêmTổng quan về Generic và Non-Generic Collection
Hiểu khái niệm Generic và Non-Generic Collection và phân biệt giữa Generic Collection và Non-Generic Collection.
Đọc thêmSử dụng mảng (Arrays)
Mảng trong C# là một cấu trúc dữ liệu lưu trữ một dãy các phần tử có bộ nhớ nằm liên tiếp nhau và có kích thước cố đinh.
Đọc thêmLập trình hướng đối tượng
Lập trình hướng đối tượng (Object Oriented Programing) hay còn gọi là OOP. Là một kỹ thuật lập trình cho phép các lập trình viên có thể ánh xạ các thực thể bên ngoài đời thực và trừu tượng hoá thành các class và object trong mã nguồn.
Đọc thêmVòng lặp (loop)
Trong thực tế khi bạn cần thực thi một khối lệnh nhiều lần. Vòng lặp cho phép chúng ta thực thi một câu lệnh hoặc một khối lệnh nhiều lần.
Đọc thêm