Như bạn đã biết, kiểu giá trị thì không thể được gán một giá trị null. Ví dụ: int i = null
sẽ gây ra lỗi khi biên dịch.
C# 2.0 đã giới thiệu các kiểu dữ liệu có thể null (nullable type) cho phép bạn gán null cho các biến kiểu giá trị. Bạn có thể khai báo các nullable type bằng cách sử dụng Nullable<T>
với T là một kiểu dữ liệu.
Nullable<int> i = null;
Một kiểu nullable có phạm vi giá trị tương tự như kiểu dữ liệu cơ sở của nó, được bổ sung thêm giá trị null
. Ví dụ: Nullable<int>
có thể được gán bất kỳ giá trị nào từ -2147483648 đến 2147483647 hoặc giá trị null.
Các kiểu nullable là các thể hiện của struct System.Nullable<T>
. Có thể xem nó giống như struct sau đây.
[Serializable]
public struct Nullable<T> where T : struct
{
public bool HasValue { get; }
public T Value { get; }
// other implementation
}
Một biến kiểu int
nullable về cơ bản cũng giống như một biến kiểu int
, chỉ khác ở chỗ biến kiểu int
nullable có thể được gán giá trị null
.
static void Main(string[] args)
{
Nullable<int> i = null;
if (i.HasValue)
{
Console.WriteLine(i.Value); // or Console.WriteLine(i)
}
else
{
Console.WriteLine("Null");
}
}
Đây là kết quả khi biên dịch và chạy chương trình:
Null
Thuộc tính HasValue
trả về true nếu đối tượng đã được gán một giá trị; nếu nó chưa được gán bất kỳ giá trị nào hoặc đã được gán một giá trị null, nó sẽ trả về false .
Truy cập giá trị của biến bằng thuộc tính Value
sẽ ném ra một ngoại lệ lúc thực thi nếu biến kiểu nullable là null hoặc không được gán bất kỳ giá trị nào. Ví dụ dưới đây sẽ minh họa điều này:
Để tránh xảy ra ngoại lệ như trên, bạn có thể sử dụng phương thức GetValueOrDefault()
để nhận giá trị thực nếu nó không phải là null và giá trị mặc định nếu nó là null. Ví dụ sau minh họa về cách sử dụng phương thức GetValueOrDefault()
:
static void Main(string[] args)
{
Nullable<int> i = null;
Console.WriteLine(i.GetValueOrDefault());
}
Bạn có thể dùng toán tử ?
để viết tắt cú pháp khai báo biến kiểu nullable. Ví dụ int?
, long?
thay vì sử dụng Nullable<T>
.
int? i = null;
double? d = null;
Sử dụng toán tử ??
để trả về một giá trị mặc định nếu biến ở bên trái toán tử ??
có giá trị null.
Ví dụ dưới đây sẽ kiểm tra biến i
có bị null không bằng cách sử dụng toán tử ??
. Nếu biến i
khác null thì sẽ trả về giá trị của i
, ngược lại sẽ trả về 0.
int? i = null;
int j = i ?? 0;
Console.WriteLine(j);
Đây là kết quả khi biên dịch và chạy chương trình:
0
Một kiểu nullable có các quy tắc gán giống như một kiểu giá trị. Nó phải được gán một giá trị trước khi sử dụng nó nếu các kiểu nullable được khai báo trong một phương thức dưới dạng các biến cục bộ. Nếu nó là một trường của bất kỳ lớp nào thì nó sẽ có giá trị null theo mặc định.
Ví dụ, biến i
kiểu int
nullable được khai báo và sử dụng mà không gán bất kỳ giá trị nào. Trình biên dịch sẽ đưa ra lỗi Use of unassigned local variable 'i':
Trong ví dụ sau, trường i
kiểu int
nullable của lớp MyClass, vì vậy nó mặc định sẽ được gán giá trị null
và không xảy ra bất kỳ lỗi nào khi biên dịch.
class MyClass
{
public Nullable<int> i;
}
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
if (myClass.i == null)
{
Console.WriteLine("Null");
}
}
}
Đây là kết quả khi biên dịch và chạy chương trình:
Null
Null
đồng nghĩa với không có bất kỳ giá trị gì. Vì vậy, các toán tử so sánh sẽ không hoạt động với null
. Ví dụ sau sẽ minh họa điều này:
static void Main(string[] args)
{
int? i = null;
int j = 10;
if (i < j)
{
Console.WriteLine("i < j");
}
else if ( i > 10)
{
Console.WriteLine("i > j");
}
else if ( i == 10)
{
Console.WriteLine("i == j");
}
else
{
Console.WriteLine("Could not compare");
}
}
Đây là kết quả khi biên dịch và chạy chương trình:
Could not compare
Lớp Nullable là lớp tĩnh trợ giúp cho các kiểu nullable. Nó cung cấp một phương thức so sánh để so sánh các kiểu nullable. Nó cũng có một phương thức GetUnderlyingType
trả về kiểu cơ bản của kiểu nullable.
static void Main(string[] args)
{
int? i = null;
int j = 10;
if (Nullable.Compare<int>(i, j) < 0)
{
Console.WriteLine("i < j");
}
else if (Nullable.Compare<int>(i, j) > 0)
{
Console.WriteLine("i > j");
}
else
{
Console.WriteLine("i = j");
}
}
Đây là kết quả khi biên dịch và chạy chương trình:
i < j
Value
sẽ ném ra một ngoại lệ UnlimitedOperationException
nếu giá trị là null; ngược lại nó sẽ trả về giá trị.HasValue
trả về true nếu biến chứa giá trị hoặc false nếu nó là null.==
và !=
với kiểu nullable. Để thực hiện các so sánh khác, bạn phải sử dụng lớp tĩnh Nullable.Nullable<Nullable<int>> i;
sẽ gây ra một lỗi lúc biên dịch.Những điểm cần nhớ:
?
là một cú pháp tốc ký cho các kiểu nullable.Value
để lấy giá trị của loại nullable, tuy nhiên thuộc tính Value
sẽ ném ra một ngoại lệ UnlimitedOperationException
nếu giá trị là null.HasValue
để kiểm tra xem kiểu nullable có được gán giá trị hay không.Nullable
là lớp trợ giúp để so sánh các kiểu nullable.Bạn không nghe lầm đâu, trước đây chỉ có kiểu giá trị nullable, nhưng từ phiên bản C# 8.0 mới được Microsoft phát hành kèm theo .NET Framework 4.8, bạn sẽ có thêm kiểu tham chiếu nullable.
C# 8.0 giới thiệu các kiểu tham chiếu nullable và các kiểu tham chiếu không nullable cho phép bạn đưa ra các khai báo quan trọng về các thuộc tính cho các biến kiểu tham chiếu:
Một tham chiếu không được coi là null: Khi các biến không được coi là null, trình biên dịch sẽ thực thi các quy tắc đảm bảo an toàn để hủy đăng ký tới các biến này mà không cần kiểm tra trước rằng nó không null:
null
.Một tham chiếu có thể là null: Khi các biến có thể là null, trình biên dịch sẽ thực thi các quy tắc khác nhau để đảm bảo rằng bạn đã kiểm tra chính xác tham chiếu null:
null
mặc định và có thể được gán giá trị null
trong mã.Tính năng mới này cung cấp các lợi ích đáng kể trong việc xử lý các biến tham chiếu trong các phiên bản trước của C# trong đó mục đích thiết kế không thể được xác định lúc khai báo biến.
Trình biên dịch không cung cấp các xử lý an toàn trước các ngoại lệ tham chiếu null cho các kiểu tham chiếu:
Với việc bổ sung các kiểu tham chiếu nullable, bạn có thể khai báo ý định thiết kế của mình rõ ràng hơn. Các giá trị null
là cách chính xác để đại diện cho rằng một biến không đề cập đến một giá trị.
Không sử dụng tính năng này để xóa tất cả các giá trị null
khỏi mã của bạn. Thay vào đó, bạn nên khai báo ý định của mình với trình biên dịch và các nhà phát triển khác đọc mã của bạn.
Bằng cách khai báo ý định của bạn, trình biên dịch sẽ thông báo cho bạn khi bạn viết mã không phù hợp với ý định đó.
Một kiểu tham chiếu nullable được khai báo bằng cách sử dụng cú pháp giống như kiểu giá trị nullable: sử dụng ký tự ?
ngay sau kiểu dữ liệu của biến. Ví dụ: khai báo biến dưới đây minh họa biến name
kiểu string nullable:
string? name;
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong loạt bài này, tôi sẽ xem xét một số
Ngôn ngữ C# đã bật các bộ tăng áp liên
Trong bài viết này, chúng ta sẽ tìm hiểu lớp tiện ích ZipFile trong C#, cách nén tập tin và thư mục, cùng với giải nén tập tin zip.
Bài viết này sẽ giới thiệu cách đơn giản nhất mà tôi đã tìm thấy để đọc và ghi file Excel bằng C# sử dụng ExcelMapper.