C#

C# là gì

C# (hay C sharp) là một ngôn ngữ lập trình đơn giản, được phát triển bởi đội ngũ kỹ sư của Microsoft vào năm 2000. C# là ngôn ngữ lập trình hiện đại, hướng đối tượng và được xây dựng trên nền tảng của hai ngôn ngữ mạnh nhất là C++ và Java.

Các đặc điểm

  • Tương đối dễ dàng hơn: Bắt đầu với C# có thể gọi là tương đối dễ dàng hơn so với các ngôn ngữ lập trình khác

  • Sử dụng phát triển rộng hơn: Sử dụng C#, bạn có thể tạo các ứng dụng web, ứng dụng di động, ứng dụng máy tính hay trò chơi. C# có một số tính năng tuyệt vời như bộ thu gom rác tự động, interface, v.v. giúp xây dựng các ứng dụng tốt hơn.

  • Đối tượng mục tiêu lớn hơn: Việc được hỗ trợ bởi Microsoft mang lại lợi thế cho các ứng dụng được tạo bằng C# vì nó sẽ có mục tiêu rộng hơn.

Vì C# là một ngôn ngữ lập trình được sử dụng rộng rãi như vậy, nên rất nhiều tổ chức lớn và nhỏ sử dụng sản phẩm của họ.

CLR

Common Language Runtime (CLR) xử lý chương trình thực thi chương trình cho nhiều ngôn ngữ khác nhau bao gồm cả C#. Kiến trúc của CLR xử lý quản lý bộ nhớ, thu gom rác, xử lý bảo mật

Garbage Collection

Bộ dọn rác (garbage collection) là quá trình giải phóng bộ nhớ bị chiếm bởi các đối tượng không mong muốn. Khi bạn tạo một đối tượng, tự động một số không gian bộ nhớ được cấp cho đối tượng trong bộ nhớ heap. Bây giờ, sau khi bạn thực hiện tất cả các hành động trên đối tượng, không gian bộ nhớ bị chiếm bởi đối tượng sẽ trở thành lãng phí. Sẽ là cần thiết để giải phóng bộ nhớ. Việc thu gom rác xảy ra trong ba trường hợp:

  • Nếu bộ nhớ bị chiếm bởi các đối tượng vượt quá ngưỡng giá trị đặt trước.

  • Nếu phương thức thu gom rác được gọi

  • Nếu hệ thống của bạn có bộ nhớ vật lý thấp

Các kiểu class trong C#

  • static class: khai báo bởi từ khoá static không cho phép kế thừa. Do đó không thể tạo đối tượng từ static class.

  • partial class: khai báo bởi từ khoá partial cho phép các thành viên của nó phân chia hoặc chia sẻ với file (.cs) nguồn.

  • abstract class: là lớp không thể khởi tạo nên bạn không thể tạo đối tượng. abstract class hoạt động dựa trên khái niệm trừu tượng trong OOP. Tính trừu tượng giúp trích xuất các chi tiết cần thiết và ẩn những chi tiết không cần thiết.

  • sealed class: Lớp được đóng dấu là lớp không thể được kế thừa. Sử dụng từ khóa sealead để hạn chế quyền truy cập đối với người dùng kế thừa lớp đó.

So sánh Interface và Abstract

Multiple inheritance

Một class có thể hiện thực nhiều interface.(tạm coi là thừa kế)

Không hỗ trợ đa thừa kế

Default implementation

Không thể định nghĩa code xử lý, chỉ có thể khai báo.

Có thể định nghĩa thân phương thức, property.

Access Modifiers

Mọi phương thức, property đều mặc định là public.

Có thể xác định modifier.

Adding functionality

Mọi phương thức, property của interface cần được hiện thực trong class.

Không cần thiết.

Fields and Constants

Không

  • Các lớp trừu tượng là các lớp không thể được khởi tạo tức là chúng không thể tạo một đối tượng. Interface giống như một lớp trừu tượng vì tất cả các phương thức bên trong interface đều là phương thức trừu tượng.

  • Các lớp trừu tượng có thể có cả phương thức trừu tượng và không trừu tượng nhưng tất cả các phương thức của một interface đều là phương thức trừu tượng.

  • Vì các lớp trừu tượng có thể có cả phương thức trừu tượng và không trừu tượng, chúng ta cần sử dụng từ khóa abstract để khai báo các phương thức trừu tượng. Nhưng trong interface, không cần như vậy.

  • Một lớp trừu tượng có các hàm tạo trong khi một interface thì không

Generic trong C#

Trong C#, lập trình tổng quát (generics) là một dạng lập trình đặc biệt trong đó kiểu dữ liệu (của biến thành viên, biến cục bộ, tham số, kiểu trả về của phương thức,...) không được xác định ở giai đoạn xây dựng đơn vị code (như lớp, phướng thức) mà chỉ được xác định ở giai đoạn khởi tạo và sử dụng.

Để thực hiện điều này, ở giai đoạn khai báo người ta dùng một kiểu dữ liệu giả. Ở giai đoạn sử dụng, kiểu dữ liệu giả sẽ được thay thế bằng kiểu dữ liệu thực. Cú pháp dùng cho generic:£

GenericList<float> list1 = new GenericList<float>();
GenericList<Features> list2 = new GenericList<Features>();
GenericList<Struct> list3 = new GenericList<Struct>();

Sự khác biệt giữa Array và ArrayList trong C#

Array (mảng) là một tập hợp biến có cùng kiểu được gộp lại dưới một cái tên. Trong khi ArrayList là tập hợp các đối tượng có chỉ mục riêng biệt. Với ArrayList bạn có thể truy cập với các tính năng như cấp phát bộ nhớ động, thêm, tìm và sắp xếp mục trên ArrayList.

  • Khi khai bao một mảng ta phải thiết lập kích cỡ tĩnh, do đó bộ nhớ là cố định. Trong khi ArrayList, có thể tăng giảm tuỳ ý.

  • Mảng đi cùng với namespace system.array trong khi ArrayList đi cùng với namespace system.collection.

  • Tất cả mục trong một mảng có cùng kiểu dữ liệu trong khi ArrayList có thể giống hoặc khác kiểu dữ liệu.

  • Trong khi mảng không chấp nhận null, thì ArrayList chấp nhận giá trị null

Boxing và Unboxing trong C#

Boxing là quá trình chuyển dữ liệu từ kiểu tham trị sang kiểu tham chiếu.Quá trình boxing một biến kiểu tham trị sẽ khởi tạo một đối tượng trong vùng nhớ heap và sao chép giá trị của biến tham trị vào đối tượng mới này. Và quá trình boxing được thực hiện nhờ quá trình chuyển đổi ngầm định.

int num = 23; // 23 will assigned to num
Object Obj = num; // Boxing

Unboxing là quá trình ngược lại với Boxing, tức là đưa từ kiểu tham chiếu ra kiểu tham trị. Quá trình này sẽ được thực hiện một cách tường minh. Gồm có 2 bước :

  1. Kiểm tra chắc chắn rằng đối tượng đã được boxing đúng kiểu giá trị đưa ra.

  2. Sao chép giá trị sang biến dữ liệu kiểu tham trị.

int num = 23;         // value type is int and assigned value 23
Object Obj = num;    // Boxing
int i = (int)Obj;    // Unboxing

== và equals() trong C#?

Cả hai đều dùng cho so sánh giá trị đối tượng, ví dụ:

int x = 10;
int y = 10;
Console.WriteLine( x == y);
Console.WriteLine(x.Equals(y));

// Output:
// True
// True

Toán tử ==: là một kiểu tham chiếu có nghĩa là nó sẽ trả về true nếu điểm tham chiếu đến đối tượng giống nhau.

Phương thức Equals() dùng so sánh giá trị hai được mang bởi các đối tượng. Trả về true khi tất cả giá trị được mang bởi đối tượng bằng nhau.

Nạp chồng trong C#

Nạp chồng (Overloading) có nghĩa là khi các phương thức có cùng tên nhưng mang các giá trị khác nhau để sử dụng trong một ngữ cảnh khác. Chỉ có phương thức main() không thể được nạp chồng.

Để thực hiện phương thức nạp chồng trong C#:

  • Thay đổi số lượng tham số

  • Thay đổi thứ tự tham số

  • Sử dụng kiểu dữ liệu khác nhau cho tham số

const và readonly trong C#

Từ khoá const trong C# dùng để khai báo hằng trong suốt chương trình. Điều này có nghĩa là sau khi biến được khai báo là hằng, giá trị của nó không thể thay đổi.

Trong C# hằng là một số, chuỗi, tham chiếu null hoặc giá trị boolean.

class IB {
 
    // Constant fields
    public const int xvar = 20;
    public const string str = "InterviewBit";
    
    // Main method
    static public void Main()
    {
    
        // Display the value of Constant fields
        Console.WriteLine("The value of xvar: {0}", xvar);
        Console.WriteLine("The value of str: {0}", str);
    }
}

Kết quả:

The value of xvar is 20.
The value of string is Interview Bit

Mặt khác, từ khoá readonly chỉ có thể gán biến khi nó được khai báo hoặc trong một constructor của cùng một lớp mà nó được khai báo.

public readonly int xvar1;
   public readonly int yvar2;
 
   // Values of the readonly 
   // variables are assigned
   // Using constructor
   public IB(int b, int c)
   {
 
       xvar1 = b;
       yvar2 = c;
       Console.WriteLine("The value of xvar1 {0}, "+
                       "and yvar2 {1}", xvar1, yvar2);
   }
 
   // Main method
   static public void Main()
   {
     IB obj1 = new IB(50, 60);
   }
}

Kết quả:

The value of xvar1 is 50, and yvar2 is 60
  • const là tĩnh theo mặc định trong khi readonly nên có một giá trị được gán khi phương thức khởi tạo được khai báo.

  • const có thể được khai báo trong các hàm trong khi các sửa đổi readonly có thể được sử dụng với các kiểu tham chiếu.

String và StringBuilder

Sự khác biệt chính giữa String và StringBuilder là các đối tượng String là bất biến trong khi StringBuilder tạo ra một chuỗi ký tự có thể thay đổi. StringBuilder sẽ thực hiện các thay đổi đối với đối tượng hiện có hơn là tạo đối tượng mới.

StringBuilder đơn giản hóa toàn bộ quá trình thực hiện thay đổi đối với đối tượng chuỗi hiện có. Vì lớp String là bất biến nên sẽ tốn kém hơn khi tạo một đối tượng mới mỗi khi chúng ta cần thực hiện thay đổi. Vì vậy, lớp StringBuilder xuất hiện có thể được gợi lên bằng cách sử dụng không gian tên System.Text.

Trong trường hợp, một đối tượng chuỗi sẽ không thay đổi trong toàn bộ chương trình, thì hãy sử dụng lớp String hoặc StringBuilder khác.

string s = string.Empty; 
for (i = 0; i < 1000; i++) 
{ 
    s += i.ToString() + " "; 
}

Tại đây, bạn sẽ cần tạo 2001 đối tượng trong đó 2000 sẽ không được sử dụng.

Điều tương tự có thể được áp dụng bằng cách sử dụng StringBuilder:

StringBuilder sb = new StringBuilder(); 
for (i = 0; i < 1000; i++) 
{ 
   sb.Append(i); sb.Append(' '); 
}

Bằng cách sử dụng StringBuilder ở đây, bạn cũng giảm bớt căng thẳng cho bộ cấp phát bộ nhớ.

Nguồn tham khảo

Last updated