Bài 2: Các khái niệm và nguyên tắc cơ bản của NET Framework - Nền tảng lập trình C#


Trong các ngôn ngữ lập trình cấp cao luôn có các qui định về định nghĩa dữ liệu trong lập trình. Mỗi kiểu dữ liệu trong .NET là một đối tượng, nghĩa là nó có các thuộc tính và phương thức riêng


Tổng quan về .NET Framework

  • .NET Framework là thành phần nền tảng cho mọi công cụ phát triển ứng dụng .NET
  • .NET Framework được thiết kế nhằm hỗ trợ cho các trình ứng dụng và các service thế hệ kế tiếp
  • Cung cấp các lớp đối tượng (Class) để có thể gọi thi hành các chức năng mà đối tượng đó cung cấp
  • Cung cấp hơn 5000 lớp đối tượng để gọi thực hiện đủ các loại dịch vụ từ hệ điều hành

Kiến trúc

Kiến trúc Framework

Hệ thống namespace trong .NET Framework

Hệ thống namespace trong Framework

Các kiểu dữ liệu

  • Khái niệm
    • Trong các ngôn ngữ lập trình cấp cao luôn có các qui định về định nghĩa dữ liệu trong lập trình
    • Kiểu là khái niệm ám chỉ việc định nghĩa hình thái, cấu trúc và giá trị của dữ liệu, bao gồm cách biểu diễn và xử lý của dữ liệu
    • Kiểu dữ liệu trong .NET được mô tả chi tiết trong một cấu trúc gọi là Common Type System (CTS)
  • Kiểu dữ liệu trong .NET được chia thành nhiều loại:
    • Kiểu giá trị (Value Types)
    • Kiểu tham chiếu (Reference Types)
    • Kiểu do người dùng định nghĩa (User-defined Types)
    • Kiểu liệt kê (Enumerations)
  • Mỗi kiểu dữ liệu trong .NET là một đối tượng, nghĩa là nó có các thuộc tính và phương thức riêng. Một trong những phương thức thường dùng nhất là Parse và ToString
  • Cách tạo và sử dụng các kiểu dữ liệu
    • Các kiểu giá trị (Value Types)
    • Các kiểu tham chiếu (Reference Types)

Các kiểu giá trị (Value Types)

  • Bao gồm các kiểu dữ liệu số học ngày giờ, kiểu luận lý, kiểu do người dùng định nghĩa và kiểu liệt kê
  • Các biến có kiểu giá trị là những biến chứa trực tiếp dữ liệu của chúng thay vì chứa một tham chiếu tới dữ liệu được lưu trữ tại một nơi nào đó trong bộ nhớ (memory)
  • Các instance của kiểu giá trị được lưu trữ trong một vùng nhớ được gọi là stack, ở đó tại thời điểm vận hành (runtime) có thể tạo (create), đọc (read), cập nhật (update), và loại bỏ (remove) chúng một cách nhanh chóng

Các kiểu giá trị tổng quát:

  • Các kiểu giá trị được xây dựng sẵn (Built-in types)
  • Các kiểu do người dùng định nghĩa (User-defined types)
  • Các kiểu liệt kê (Enumerations)

Kiểu giá trị được xây dựng sẵn (Built-in types)

  • Là các kiểu cơ sở do NET Framework cung cấp, các kiểu dữ liệu khác đều được xây dựng dựa trên các kiểu dữ liệu cơ sở này
  • Tất cả các kiểu dạng số (numeric types) được xây dựng sẵn đều thuộc loại kiểu giá trị
  • Việc sử dụng alias hoàn toàn tương đương với cách sử dụng tên kiểu theo cách đầy đủ, tuy nhiên hầu hết các lập trình viên sử dụng alias để chúng ngắn gọn hơn.
  • Khi gán các biến kiểu giá trị với nhau, dữ liệu được sao chép từ biến này tới biến kia và được lưu trữ tại hai vị trí khác nhau trên stack
  • Các kiểu giá trị thường được dùng để trình bày các giá trị đơn giản
  • Bảng sau liệt kê các kiểu số thường dùng nhất:

Kiểu alias miền giá trị trong C#

Kiểu alias miền giá trị trong C#

Kiểu do người dùng định nghĩa (User-defined Types)

  • Kiểu do người dùng định nghĩa còn được gọi là các struct. Giống như các kiểu giá trị khác, các instance của các kiểu do người dùng định nghĩa được lưu trữ trên stack và chứa trực tiếp dữ liệu của chúng
  • struct là một kiểu cấu trúc hỗn hợp của nhiều kiểu khác nhằm mục đích dễ dàng làm việc với dạng dữ liệu quan hệ
  • struct có cấu trúc tương tự như class, tuy nhiên struct có kiểu giá trị còn class có kiểu tham chiếu
//Khởi tạo
struct Nhan_Vien
{
  public string Ma_so;
  public string Ho_ten;
  public date Ngay_sinh;
  public double He so luong;
}

//Khai báo biến nhân viên và gán các giá trị
Nhan_Vien nv;
nv.Ma_so = "MS01"
nv.Ho_ten = "Võ Nhật Nam"
nv.Ngay_sinh = DateTime.Parse("10/10/1989")
nv.He_so_luong = 2.0

Kiểu liệt kê (Enumerations)

  • Kiểu liệt kê là các ký hiệu có cùng một họ (có liên quan với nhau) có các giá trị cố định.
  • Kiểu liệt kê được dùng để cung cấp một danh sách chọn lựa cho lập trình viên sử dụng
  • Lưu ý: khi khai báo kiểu liệt kê chỉ có thể sử dụng các kiểu số nguyên như byte, sbyte, short, ushort, int, uint, long hoặc ulong
enum Titles : int { Mr, Ms, Mrs, Dr };

Ví dụ Enumerations

Cách khai báo các kiểu giá trị

Các kiểu giá trị có một khởi tạo (constructor) ngầm định, do vậy bạn không cần phải bao gồm trong phần khai báo từ khóa New như khi khai báo với class

bool b = false;

Trong C# mỗi câu lệnh được kết thúc bởi dấu ";"

.NET cung cấp một kiểu mới đó là kiểu Nullable cho phép kiểm tra liệu một biến đã được gán giá trị hay chưa

Nullable<bool> b = null;
// C# cho phép sử dụng ký hiệu thể hiện nhanh như sau
bool? b = null;

Một biến có kiểu nullable cho phép sử dụng các thành viên HasValue và Value. Bạn có thể sử dụng HasValue để kiểm tra liệu có hay không một giá trị đã được thiết lập

if (b.HasValue)
  Console.WriteLine("b is {0}.", b.Value);
else
  Console WriteLine("b is not set ");

Các kiểu tham chiếu (Reference Types)

  • Các kiểu tham chiếu lưu trữ địa chỉ dữ liệu của chúng c , cũng được hiểu như là một con trỏ (pointer), trên stack.
  • Dữ liệu thực sự mà các tham chiếu địa chỉ tham chiếu tới được lưu trữ trong một vùng bộ nhớ được gọi là heap
  • Hầu hết các kiểu trong .NET Framework là kiểu tham chiếu. Các kiểu tham chiếu cung cấp rất nhiều cho tính linh động, uyển chuyển, chúng mang đến khả năng thực thi hoàn hảo khi gởi chúng tới các phương thức

Các kiểu tham chiếu được xây dựng sẵn

  • Thời điểm vận hành (runtime) quản lý bộ nhớ bằng việc sử dụng heap thông qua một tiến trình được gọi là garbage collection. Garbage collection sẽ khởi tạo bộ nhớ theo chu kỳ dựa theo nhu cầu bằng cách loại bỏ các đối tượng không còn được tham chiếu nữa.
  • Có khoảng 2500 kiểu tham chiếu được xây dựng sẵn trong .NET Framework (không được dẫn xuất từ System.ValueType)
  • Các kiểu tham chiếu thường dùng:

Các kiểu tham chiếu thường dùng

Sử dụng string và StringBuilder

Khi có bất kỳ sửa đổi đối với chuỗi tại thời điểm vận hành sẽ tạo nên một chuỗi mới và bỏ đi chuỗi cũ

string s = "this is some text to search";
s = s.Replace("search", "replace");
Console.WriteLine(s);

Đoạn mã lệnh sau đây sẽ cấp phát bốn chuỗi mới trong bộ nhớ: Chỉ chuỗi sau cùng là có một tham chiếu; ba chuỗi kia sẽ được dispose khi công cụ thu gom rác làm việc

string s;
s = "wombat"; // "wombat"
s += " kangaroo"; // "wombat kangaroo"
s += " wallaby"; // "wombat kangaroo wallaby"
s += " koala"; // "wombat kangaroo wallaby koala"
Console.WriteLine(s);

Việc ngăn ngừa các loại chuỗi tạm thời này giúp tránh gom rác không cần thiết, cải thiện hiệu suất hoạt động. Có một số cách để ngăn ngừa các chuỗi tạm thời:

  • Sử dụng các phương thức Concat, Join, hay Format của lớp String ghép nhiều item trong một câu lệnh đơn lẻ
  • Sử dụng lớp StringBuilder để tạo các chuỗi dạng dynamic (có thể biến đổi - mutable)
System.Text.StringBuilder sb = new
System.Text.StringBuilder(30);
sb.Append("wombat"); // Build string.
sb.Append(" kangaroo");
sb.Append(" wallaby");
sb.Append(" koala ); ");
string s = sb.ToString(); // Copy result to string.
Console.WriteLine(s);

Sự chuyển đổi giữa các kiểu

  • Chuyển đổi ngầm định: C# chấp nhận sự chuyển kiểu ngầm định nếu kiểu đích có thể thích hợp với tất cả các giá trị có thể nhận từ kiểu nguồn.
  • Chuyển đổi tường minh: tất cả các biến trong C# phải được khai báo kiểu một cách rõ ràng, và trình biên dịch kiểm tra tính nhất quán về kiểu của biểu thức.
int i = 1;
double d = 1.0001;
d = i; // Sự chuyển đổi được chấp nhận
  • Có thể thực hiện việc chuyển đổi kiểu tường minh bằng cách sử dụng toán tử chuyển kiểu (hay ép kiểu - cast operator), nó có dạng:
long L = 32769;
int I = (int) L;
  • Cơ chế Boxing và Unboxing: boxing chuyển đổi một kiểu giá trị tới một kiểu tham chiếu, và unboxing chuyển đổi một kiểu tham chiếu tới một kiểu giá trị.
int i = 123;
object o = (object) i; // cơ chế boxing

object j = 123;
int k = (int)j; //cơ chế unboxing
  •  Sử dụng toán tử as: toán tử as cũng được dùng giống như ép kiểu với một số lưu ý:
int j;
object i = "35";
j = i as int ;
// Đoạn lệnh trên sẽ xảy ra lỗi do int là kiểu giá trị
//Nếu không thể chuyển đổi kiểu nó s , nó sẽ trả về giá trị null
string j;
object i = "35";
j = i as string;
if (j == null)
  Console.WriteLine("i không phải là chuỗi");
else
  Console.WriteLine("i là chuỗi");

 

  • Sử dụng các phương thức Convert: 
    • Các thành viên public được chia sẽ của lớp System.Convert có thể được sử dụng để chuyển đổi một kiểu dữ liệu cơ sở tới kiểu dữ liệu cơ sở khác
    • Sử dụng Object Browser để xem và tìm hiểu những phương thức chuyển đổi sẵn có (Để mở công cụ Object Browser: chọn thưc đơn view => Object Browser)

Chuyển đổi convert

//chuyển đổi từ kiểu số thực sang kiểu số nguyên
double SoThuc = 23.15;
try
{
  int SoNguyen = System.Convert.ToInt32(SoThuc);
}
catch (System.OverflowException)
{
  System.Console.WriteLine("Lỗi do số cần chuyển lớn hơn biến chứa kết quả chuyển.");
}
//chuyển đổi từ kiểu số thực sang kiểu chuỗi
double SoThuc = 23.15;
string strNumber = System.Convert.ToString(SoThuc);
//Sử dụng phương thức Parse của kiểu dữ liệu:
//Ví dụ 1: gán giá trị vào cho biến có kiểu ngày
DateTime Ngay = DateTime.Parse("01/25/2008");
//Ví dụ 2: chuyển đổi số nguyên sang số thực
double SoThuc;
int SoNguyen = 3;
SoThuc = double Parse(SoNguyen);

 

Chia sẽ bài viết :


Bài viết liên quan