Chuyển đổi kiểu dữ liệu trong C#

Chuyển đổi kiểu dữ liệu trong C# là biến đổi một kiểu dữ liệu này thành kiểu dữ liệu khác. Nó còn được gọi là ép kiểu. Trong C#, ép kiểu có hai mẫu sau:

  • Chuyển đổi kiểu ngầm định (implicit) - Việc chuyển đổi này được thực hiện bởi C# theo một phương thức an toàn kiểu (type-safe). Ví dụ: việc chuyển đổi từ các lớp kế thừa thành các lớp cơ sở.
  • Chuyển đổi kiểu tường minh (explicit) - Việc chuyển đổi này được thực hiện một cách rõ ràng bởi người dùng bằng việc sử dụng các hàm được định nghĩa trước. Các chuyển đổi kiểu tường minh cần một toán tử cast.

Ví dụ sau minh họa một sự chuyển đổi kiểu tường minh trong C#:

namespace TypeConversionApplication 
{
   public class ExplicitConversion 
   {
      public static void Main(string[] args) 
	  {
         double d = 5673.74; 
         int i;
         
         // cast double to int.
         i = (int)d;
         Console.WriteLine(i);
         Console.ReadLine();
      }
   }
}

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

5673

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

Phương thức Chuyển đổi kiểu dữ liệu trong C#

C# cung cấp các phương thức chuyển đổi kiểu có sẵn được liệt kê trong bảng sau:

STT Phương thức & Miêu tả
1 ToBoolean

Chuyển đổi một kiểu thành một giá trị Boolean, nếu có thể

2 ToByte

Chuyển đổi một kiểu thành một byte

3 ToChar

Chuyển đổi một kiểu thành một Unicode character, nếu có thể

4 ToDateTime

Chuyển đổi một kiểu (kiểu integer hoặc string) thành các cấu trúc date-time

5 ToDecimal

Chuyển đổi một kiểu số thực hoặc số nguyên thành một kiểu thập phân

6 ToDouble

Chuyển đổi một kiểu thành một kiểu double

7 ToInt16

Chuyển đổi một kiểu thành một 16-bit integer

8 ToInt32

Chuyển đổi một kiểu thành một 32-bit integer

9 ToInt64

Chuyển đổi một kiểu thành một 64-bit integer

10 ToSbyte

Chuyển đổi một kiểu thành một kiểu signed byte

11 ToSingle

Chuyển đổi một kiểu thành một số small floating point

12 ToString

Chuyển đổi một kiểu thành một string

13 ToType

Chuyển đổi một kiểu thành một kiểu đã xác định

14 ToUInt16

Chuyển đổi một kiểu thành một kiểu unsigned int

15 ToUInt32

Chuyển đổi một kiểu thành một kiểu unsigned long

16 ToUInt64

Chuyển đổi một kiểu thành một unsigned big integer

Ví dụ sau minh họa cách chuyển đổi các kiểu dữ liệu đa dạng thành kiểu dữ liệu string trong C#:

using System;

namespace TypeConversionApplication 
{
   public class StringConversion 
   {
      public static void Main(string[] args) 
      {
         int i = 75;
         float f = 53.005f;
         double d = 2345.7652;
         bool b = true;

         Console.WriteLine(i.ToString());
         Console.WriteLine(f.ToString());
         Console.WriteLine(d.ToString());
         Console.WriteLine(b.ToString());
         Console.ReadLine();
            
      }
   }
}

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

75
53.005
2345.7652
True

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

Boxing và Unboxing trong C#

Mọi kiểu dữ liệu trong C#, từ kiểu có sẵn hay do người dùng tự định nghĩa, đều được kế thừa từ lớp cơ bản là System.Object.

Boxing là quá trình chuyển đổi một kiểu giá trị thành kiểu object. Nếu bạn chưa biết kiểu giá trị là gì thì vui lòng xem lại bài Kiểu dữ liệu trong C#.

Còn unboxing là quá trình ngược lại với boxing đó là chuyển từ kiểu object sang kiểu giá trị.

int i = 123;
// boxing
object o = i;
// unboxing
i = (int)o;

Boxing

Boxing là một chuyển đổi ngầm định (implicit) của một kiểu giá trị thành kiểu object. Quá trình boxing một kiểu giá trị sẽ tạo một thể hiện đối tượng trên bộ nhớ heap và sao chép giá trị vào đối tượng mới này.

int i = 123;
// Boxing copies the value of i into object o.
object o = i;

Kết quả của câu lệnh này là tạo ra một tham chiếu đối tượng o trên stack, tham chiếu một giá trị của kiểu int, trên heap. Giá trị này là bản sao của giá trị kiểu giá trị được gán cho biến i. Sự khác biệt giữa hai biến io, được minh họa trong hình ảnh sau đây:

Boxing trong C#

Unboxing

Unboxing là một chuyển đổi tường minh (explicit) từ kiểu object sang kiểu giá trị. Unboxing gồm 2 bước:

  • Kiểm tra thể hiện đối tượng để đảm bảo rằng giá trị được boxing có thể chuyển sang kiểu giá trị.
  • Sao chép giá trị từ thể hiện đối tượng vào biến kiểu giá trị.

Ví dụ dưới đây thể hiện quá trình boxing và unboxing:

int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;   // unboxing

Quá trình unboxing được minh họa như hình sau:

Unboxing trong C#

Để quá trình unbox thành công lúc thực thi thì mục được unboxing phải là một tham chiếu tới một đối tượng được tạo ra trước đó bởi quá trình boxing một thể hiện của kiểu giá trị đó.

Cố gắng unboxing null sẽ gây ra ngoại lệ NullReferenceException. Việc cố gắng unboxing một kiểu giá trị không tương thích sẽ gây ra ngoại lệ UnlimitedCastException.

Ví dụ sau đây cho thấy một trường hợp unboxing không hợp lệ và kết quả gây ra ngoại lệ UnlimitedCastException. Sử dụng trycatch, một thông báo lỗi được hiển thị khi xảy ra lỗi.

public class TestUnboxing
{
    public static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing

        try
        {
            int j = (short)o;  // attempt to unbox

            System.Console.WriteLine("Unboxing OK.");
        }
        catch (System.InvalidCastException e)
        {
            System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
        }
    }
}

Chương trình này xuất ra:

Specified cast is not valid. Error: Incorrect unboxing.

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

Nếu bạn sửa dòng này:

int j = (short) o;

thành:

int j = (int) o;

Việc chuyển đổi sẽ được thực hiện và bạn sẽ nhận được kết quả đầu ra:

Unboxing OK.

Hiệu năng

Boxing và unboxing là các quá trình tính toán tốn kém. Khi một kiểu giá trị được boxing, một đối tượng mới phải được phân bổ và xây dựng. Ở mức độ thấp hơn, việc chuyển kiểu cần thiết cho việc unboxing cũng tốn kém về mặt tính toán.

Do vậy bạn nên cân nhắc và hạn chế tối đa việc sử dụng boxing và unboxing trong quá trình lập trình.

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

Biến và Hằng số trong C# | Comdy
Biến trong C# là gì? Hằng số trong C# là gì? Cách khai báo và sử dụng biến, hằng số trong C#. Hãy xem bài viết này nhé.


Bài viết liên quan:

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.

Reflection trong C#

  • 6 min read

Reflection trong C# là gì? Ứng dụng của Reflection trong C#. Cách khai báo và sử dụng Reflection trong C#.

Attribute trong C#

  • 7 min read

Attribute trong C# là gì? Có những loại attribute nào trong C#? Làm sao để sử dụng attribute trong C#.