Skip to main content

Others

Equals và '=='

Đặc điểm

Toán tử ==

Phương thức Equals()

Loại so sánh mặc định

Kiểu tham chiếu (class): mặc định so sánh tham chiếu (trừ khi kiểu đó overload == (Ví dụ: string, record).


Kiểu giá trị (struct): chỉ một số kiểu dựng sẵn (int, double, bool, enum, char, …) có == sẵn và so sánh giá trị; với struct tự định nghĩa, không có == mặc định — muốn dùng phải tự overload.

Kiểu tham chiếu (class): mặc định là tham chiếu như == (trừ khi kiểu override Equals). string.Equals mặc định so sánh theo nội dung (giá trị).

Kiểu giá trị (struct): mặc định so sánh giá trị (field-by-field) thông qua ValueType.Equals, trừ khi bạn override/IEquatable.

Ghi đè / tuỳ biến

Có thể overload (không phải override) bằng cách khai báo public static bool operator ==(...).

Khi overload == phải overload luôn !=, và thường nên override Equals + GetHashCode cho nhất quán.

Có thể override (virtual method System.Object).


Với generics/hiệu năng, nên triển khai IEquatable<T>.Equals(T other) và đảm bảo tương thích với Equals(object) + GetHashCode().

Tính linh hoạt

Ít linh hoạt hơn (chỉ 1 toán tử; phải cẩn thận tương thích với Equals/GetHashCode).

Linh hoạt hơn: có thể override/triển khai IEquatable<T>, và có thêm object.Equals(a,b) (static) an toàn null. Với string.Equals có overload chọn StringComparison.

Tốc độ

Không có quy tắc “nhanh hơn” nói chung. Với string, == thực chất gọi string.Equals(a,b). Chênh lệch thường không đáng kể sau JIT inline.

Tương tự: phụ thuộc kiểu cụ thể và triển khai Equals. Dùng EqualityComparer<T>.Default để nhận cách so sánh tối ưu cho T.

Sử dụng với

null

An toàn (không ném NRE); a == null hợp lệ. Nếu tự overload, nhớ xử lý null đúng cách.

Gọi instance a.Equals(b) sẽ ném NRE nếu anull. Dùng object.Equals(a,b) hoặc a?.Equals(b) ?? false để an toàn null.

Generic và Non-Generic

Đặc điểm

Non-generic

Generic

Khái niệm

Là kiểu dữ liệu truyền thống. Không khai báo cụ thể khi định nghĩa class, method, interface. Kiểu dữ liệu thực tế được xác định khi sử dụng.

Là kiểu dữ liệu được tham số hoá bởi một hoặc nhiều kiểu khác nhau. Cho phép khai báo class, method, interface với kiểu cụ thể. Kiểu này sẽ được định nghĩa và sử dụng xuyên suốt.

Ưu điểm

Đơn giản, dễ hiểu


Hiệu quả cao hơn với các kiểu dữ liệu nguyên thuỷ

Tăng khả năng tái sử dụng code


Đảm bảo an toàn dữ liệu vào và ra khi sử dụng


Tốt hơn do được tối ưu hoá cho kiểu dữ liệu cụ thể

Nhược điểm

Kém linh hoạt, khó tái sử dụng.


Thiếu an toàn do có thể sử dụng sai kiểu dữ liệu

Phức tạp hơn so với non-generic.


Có thể ảnh hưởng hiệu suất với những kiểu dữ liệu phức tạp.

Sử dụng

Khi cần code đơn giản dễ hiểu, không yêu cầu tái sử dụng cao, không yêu cầu an toàn dữ liệu cao.

Khi cần code có khả năng tái sử dụng cao và yêu cầu tính an toàn dữ liệu cao.


Delegate và Event

Delegate

Event

- Là một tham chiếu đại diện cho phương thức.

- Có thể gọi trực tiếp từ bất kỳ đâu có quyền truy cập.

- Có thể gọi trực tiếp mà không có cơ chế bảo vệ nào nên có thể dẫn đến lỗi.

- Ưu tiên tính linh hoạt.

- Là thành phần của lớp sử dụng delegate để quản lý danh sách các phương thức.

- Chỉ có thể kích hoạt bên trong lớp mà nó được khai báo.

- Có cơ chế bảo vệ ngăn chặn gọi từ bên ngoài. Chỉ cho phép đăng ký bên trong class thông quan

+=

hoặc huỷ đăng ký qua

-=

- Ưu tiên an toàn và kiểm soát.