Kiểu dữ liệu trong C#

Kiểu dữ liệu trong C#

Phân loại kiểu dữ liệu

Các biến trong C# được phân loại thành 3 kiểu sau:

  • Kiểu giá trị (Value type)
  • Kiểu tham chiếu (Reference type)
  • Kiểu con trỏ (Pointer type)

Bộ nhớ Stack và Heap

Trong C# có hai loại bộ nhớ là Stack và Heap. Cả hai đều là những vùng nhớ được lưu trữ trên RAM.

Stack là vùng nhớ hoạt động theo mô hình LIFO (vào sau, ra trước) dùng để lưu trữ các biến tạm thời được tạo ra bởi các phương thức. Khi một biến được khai báo, nó được tự động đẩy vào stack (push).

Nếu phương thức kết thúc, tất cả các biến mà phương thức đó đã đẩy vào stack đều bị giải phóng (pop) và mất đi. Khi một biến bị đẩy khỏi stack, vùng nhớ nó đã chiếm có thể được sử dụng lại cho các biến khác.

Stack được CPU quản lý và tối ưu hóa cho nhiệm vụ lưu trữ biến cục bộ. Người lập trình không cần phải can thiệp vào vùng nhớ này. Tốc độ đọc ghi dữ liệu với stack rất cao, tuy nhiên kích thước của stack lại bị giới hạn.

Heap là một vùng nhớ khác cho phép chương trình tự do lưu trữ giá trị. Giá trị tạo và lưu trên heap không bị giới hạn về kích thước mà chỉ phụ thuộc và kích thước RAM. Tuy nhiên tốc độ đọc ghi dữ liệu trên heap chậm hơn so với stack.

Để sử dụng heap, chương trình phải tự mình xin cấp phát và giải phóng bộ nhớ chiếm dụng trên heap. Nếu không sử dụng hợp lý vùng nhớ này có thể dẫn đến rò bộ nhớ (memory leak), vốn rất phổ biến khi lập trình C/C++.

.NET framework hỗ trợ rất tốt việc cấp phát và quản lý bộ nhớ của chương trình qua GC (Garbage Collector) nên người lập trình .NET không cần để ý nhiều đến việc xin cấp phát và giải phóng bộ nhớ heap.

Kiểu giá trị trong C#

Các biến kiểu giá trị có thể được gán một giá trị một cách trực tiếp, giá trị này được lưu trong bộ nhớ Stack. Chúng được kế thừa từ lớp System.ValueType.

Kiểu giá trị trực tiếp chứa dữ liệu. Một số ví dụ là int, char, và float, tương ứng giữ số nguyên, chữ cái, và số thực. Khi bạn khai báo một kiểu int, hệ thống cấp phát bộ nhớ để lưu giá trị đó.

Bảng sau liệt kê các kiểu giá trị có sẵn trong C# 2010:

Kiểu Biểu diễn Dãy giá trị Giá trị mặc định
bool Giá trị Boolean True hoặc False False
byte Kiểu unsigned integer (8 bit) 0 tới 255 0
char Kiểu Unicode character (16 bit) U +0000 tới U +ffff '\0'
decimal Kiểu thập phân (128 bit) (-7.9 x 1028 tới 7.9 x 1028) / 100 to 28 0.0M
double Kiểu double (64 bit) (+/-)5.0 x 10-324 tới (+/-)1.7 x 10308 0.0D
float Kiểu float (32 bit) -3.4 x 1038 tới + 3.4 x 1038 0.0F
int Kiểu integer (32 bit) -2,147,483,648 tới 2,147,483,647 0
long Kiểu signed integer (64 bit) -9,223,372,036,854,775,808 tới 9,223,372,036,854,775,807 0L
sbyte Kiểu signed integer (8 bit) -128 tới 127 0
short Kiểu signed integer (16 bit) -32,768 tới 32,767 0
uint Kiểu unsigned integer (32 bit) 0 tới 4,294,967,295 0
ulong Kiểu unsigned integer (64 bit) 0 tới 18,446,744,073,709,551,615 0
ushort Kiểu unsigned integer (16 bit) 0 tới 65,535 0

Từ khóa sizeof trong C#

Để lấy kích cỡ chính xác của một kiểu hoặc một biến trên một nền tảng cụ thể, bạn có thể sử dụng phương thức sizeof. Biểu thức sizeof(type) hiển thị kích cỡ của đối tượng hoặc kiểu bằng giá trị byte. Ví dụ dưới đây để lấy kích cỡ của kiểu int trên bất kỳ máy tính:

using System;

namespace DataTypeApplication 
{
   public class Program 
   {
      public static void Main(string[] args) 
      {
         Console.WriteLine("Size of int: {0}", sizeof(int));
         Console.ReadLine();
      }
   }
}

Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:

Size of int: 4

Bạn có thể biên dịch và xem kết quả online tại đây.

Kiểu tham chiếu trong C#

Kiểu tham chiếu thì biến không chứa dữ liệu thực sự mà chúng chứa tham chiếu tới một vị trí bộ nhớ. Dữ liệu kiểu tham chiếu được lưu trong bộ nhớ Heap.

Việc sử dụng nhiều biến, thì kiểu tham chiếu có thể tham chiếu tới tới một vị trí bộ nhớ. Nếu dữ liệu trong vị trí bộ nhớ bị thay đổi bởi một trong số các biến, thì biến khác tự động phản ánh sự thay đổi về giá trị này. Ví dụ các kiểu tham chiếu có sẵn trong C# là: object, dynamic,string.

Kiểu object trong C#

Kiểu object là lớp cơ sở cơ bản cho tất cả kiểu dữ liệu trong C# Common Type System (CTS). Object là một alias cho lớp System.Object. Các kiểu object có thể được gán giá trị của bất kỳ kiểu, kiểu giá trị, kiểu tham chiếu, kiểu tự định nghĩa (user-defined) khác. Tuy nhiên, trước khi gán các giá trị, nó cần một sự chuyển đổi kiểu.

Khi một kiểu giá trị được chuyển đổi thành kiểu object, nó được gọi là boxing và ngược lại, khi một kiểu object được chuyển đổi thành kiểu giá trị, nó được gọi là unboxing.

object obj;
obj = 100; // this is boxing

Kiểu Dynamic trong C#

Bạn có thể lưu giữ bất kỳ kiểu giá trị nào trong biến kiểu dữ liệu dynamic. Việc kiểm tra các kiểu biến này diễn ra tại run time.

Cú pháp để khai báo một kiểu dynamic trong C# là:

dynamic <variable_name> = value;

Ví dụ:

dynamic d = 20;

Kiểu dynamic thì tương tự với kiểu object, ngoại trừ việc kiểm tra cho các biến kiểu object diễn ra tại thời điểm biên dịch (compile time), trong khi việc kiểm tra các biến kiểu dynamic diễn ra tại thời điểm thực thị (run time).

Kiểu string trong C#

Kiểu string trong C# cho phép bạn gán bất kỳ giá trị chuỗi nào cho một biến. Kiểu string là một alias cho lớp System.String. Nó kế thừa từ kiểu object. Giá trị cho một kiểu string có thể được gán bởi sử dụng các hằng chuỗi trong hai mẫu: quoted và @quoted.

Ví dụ:

string str = "Comdy";

Và một hằng chuỗi @quoted trông như sau:

@"Comdy";

Các kiểu tự định nghĩa (user-defined) trong C# là: Class, Interface, hoặc Delegate. Chúng ta sẽ bàn về các kiểu này trong các chương sau.

Các kiểu tự định nghĩa (user-defined) trong C# là: Class, Interface, hoặc Delegate. Chúng ta sẽ bàn về các kiểu này trong các chương sau.

Kiểu con trỏ trong C#

Các biến kiểu con trỏ lưu giữ địa chỉ bộ nhớ của kiểu khác. Các con trỏ trong C# có khả năng như con trỏ trong C hoặc C++.

Cú pháp để khai báo một kiểu con trỏ trong C# là:

type* identifier;

Ví dụ:

char* cptr;
int* iptr;

Chúng ta sẽ thảo luận về kiểu con trỏ ở chương: Unsafe Code trong C#.

Bạn có muốn xem bài viết tiếp theo không? Nó ở dưới đây nè.

Chuyển đổi kiểu dữ liệu trong C# | Comdy
Chuyển đổi kiểu dữ liệu trong C# là gì? Boxing và Unboxing trong C# là gì. Bài viết này sẽ hướng dẫn bạn.
Lập Trình C#Lập Trình C# Cơ Bản
Bài Viết Liên Quan:
int[] và int[,] trong C#: Ai nhanh hơn
Trung Nguyen 10/10/2020
int[] và int[,] trong C#: Ai nhanh hơn

Hiểu được sự khác biệt giữa các loại mảng trong C# sẽ giúp bạn chọn cấu trúc dữ liệu chính xác cho mọi trường hợp.

Struct và class trong C#: Ai nhanh hơn
Trung Nguyen 09/10/2020
Struct và class trong C#: Ai nhanh hơn

Trong bài viết này, tôi sẽ so sánh sự khác biệt về hiệu suất giữa struct và class trong C#: Ai nhanh hơn.

Best practice cho performance trong C#
Trung Nguyen 03/10/2020
Best practice cho performance trong C#

Mục tiêu của bài viết này là cung cấp một danh sách không đầy đủ các code mẫu cần tránh, vì chúng rủi ro hoặc performance kém.

Đọc ghi file (File I/O) trong C#
Trung Nguyen 26/04/2020
Đọc ghi file (File I/O) trong C#

Hướng dẫn này sẽ giúp bạn tìm hiểu về đọc ghi file (File I/O) trong C# và sử dụng các lớp tiện ích để đọc ghi file.