text:
Nhập môn lập trình
Một trang web (hay website) được tạo ra gồm ba yếu tố cơ bản là giao diện, nội dung và tính tương tác. Tính tương tác của trang web có được nhờ lập trình.
Lập trình với ASP.NET bao gồm hai ngôn ngữ phổ biến là Visual Basic (VB) và C#. Mỗi ngôn ngữ đòi hỏi nhiều thời gian và công sức để khám phá. Trong chương này chỉ tìm hiểu những nét cơ bản nhất trong Visual Basic (VB) và C#.
Sơ lược về quá trình biên dịch của ASP.NET run time
Khi ASP.NET run time yêu cầu một trang aspx nào đó, nếu trang chứa code (VB hay C#), thì nó sẽ biên dịch (compile) các code này sang ngôn ngữ MSIL (Microsoft Intermediate Language) để .NET Framework có thể hiểu và thực thi. Kết quả của quá trình biên dịch sẽ là một loạt các file có phần mở rộng là DLL và được lưu trong một thư mục tạm nào đó trong máy tính. Quá trình biên dịch chỉ diễn ra khi trang aspx được yêu cầu lần đầu, những lần yêu cầu sau với trang này, ASP.NET run time sẽ dùng lại các file DLL được tạo ra trước đó.
Kiểu dữ liệu
Các ngôn ngữ lập trình thường cung cấp một danh sách các kiểu dữ liệu (data type) khác nhau dùng để biểu diễn các kiểu thông tin khác nhau như số (numbers), thời gian (date, time), văn bản (text), v.v.
Microsoft .NET hỗ trợ rất nhiều ngôn ngữ lập trình như C#, VB, v.v. và các ngôn ngữ này có thể giao tiếp được với nhau. Ví dụ khi biên dịch file C# thành các file DLL thì các file DLL này có thể được dùng trong ứng dụng VB. Vì các ngôn ngữ lập trình có thể giao tiếp qua lại với nhau nên cần có một hệ thống các kiểu chung để các ngôn ngữ có thể hiểu được nhau, hệ thống này được gọi là CTS (Common Type System). Mỗi ngôn ngữ lập trình sẽ định nghĩa cho mình các kiểu dữ liệu và chúng tham chiếu đến kiểu dữ liệu chung trong CTS. Ví dụ, trong VB có kiểu integer, C# có kiểu int, và cả hai kiểu này cùng tham chiếu đến kiểu System.Int32 trong CTS.
Bảng dưới đây là danh sách các kiểu trong CTS và tương ứng với chúng trong C# hay VB:
Biến
Để làm việc với các dữ liệu, chúng ta cần lưu trữ nó trong một biến. Cú pháp khai báo một biến trong VB là:
Dim tên_biến As Kiểu_Dữ_Liệu
Trong C#
Kiểu_Dữ_Liệu tên_biến;
Khai báo biến bắt đầu bằng từ khoá Dim. tên_biến là tên của biến cần khai báo gồm các kí tự, số, dấu _, và không được bắt đầu bằng số. Từ khoá As dùng để chỉ kiểu dữ liệu cho biến. Kiểu_Dữ_Liệu là một trong các kiểu dữ liệu (VB) ở bảng trên.
Với C#, thứ tự tên_biến và Kiểu_Dữ_Liệu ngược lại.
Ví dụ khai báo một biến kiểu Integer, tên biến là x và một biến kiểu String, tên biến là s như sau:
Mã VB
Dim x As Integer Dim s As String
Mã C#
int x; string s;
Sau khi khai báo biến, chúng ta có thể gán giá trị cho chúng, ví dụ với hai biến trên và để ý đối với biến s kiểu String thì giá trị của nó là một chuỗi kí tự được đặt trong cặp dấu “:
x = 5 s = "Hello "
Chúng ta cũng có thể kết hợp khai báo và gán giá trị cho biến như ví dụ:
Mã VB
Dim x As Integer = 5 Dim s As String = "Hello"
Mã C#
int x = 5; string s = "Hello ";
Một số chú ý khi đặt tên biến:
- Không bắt đầu bằng số.
- Không trùng với các từ khoá (keywords), là các từ vựng có sẵn trong ngôn ngữ.
- Đặt theo mục đích, ví dụ firstName, age.
- Tuân theo chuẩn camel case, tức là nếu tên biến gồm nhiều từ như firstName (gồm first và Name) thì từ đầu tiên viết thường tất cả các kí tự, các từ kế tiếp sẽ viết hoa kí tự đầu tiên, như firstName.
Chuyển và ép kiểu
Chuyển kiểu (converting data types) thường dùng phương thức ToString() để chuyển một kiểu bất kì về kiểu String hay có thể dùng các phương thức trong lớp Convert. Xem các ví dụ:
Mã VB
Label1.Text = System.DateTime.Now.ToString() Dim myBoolean1 As Boolean = Convert.ToBoolean("True")
Mã C#
Label1.Text = System.DateTime.Now.ToString(); bool myBoolean1 = Convert.ToBoolean("True");
Bên cạnh phương thức ToBoolean chuyển một kiểu đến kiểu Boolean thì trong Convert còn có các phương thức ToInt32 (chuyển đến kiểu số nguyên), phương thức ToDateTime (chuyển đến thời gian), phương thức ToString (chuyển đến chuỗi) (chú ý đây là phương thức của lớp Convert, phương thức ToString ở trên là của một object bất kì).
Kĩ thuật chuyển kiểu (converting) chuyển giá trị của một kiểu dữ liệu sang giá trị mới. Còn một phương pháp khác để chuyển kiểu là ép kiểu (casting). Ép kiểu thật sự biến một kiểu thành một kiểu khác. Trong VB có hai cách dùng để ép kiểu là dùng CType và DirectCast (hay TryCast). CType ép kiểu hai đối tượng giống nhau, DirectCast ép hai kiểu tương thích nhau. Xem ví dụ:
Mã VB
Dim o1 As Object = 1 Dim i1 As Integer = DirectCast(o1, Integer) Dim i2 As Integer = CType(o1, Integer) Dim o2 As Double = 1 Dim i3 As Integer = DirectCast(o2, Integer) Dim i4 As Integer = CType(o2, Integer)
i1 và i2 thành công vì o1 là một Integer, i3 không thành công vì hai kiểu Integer và Double không tương thích nhau, i4 thành công vì o2 trông như một số nguyên.
Trong C# có hai cách ép kiểu:
- Cách thứ nhất là đặt biểu thức gồm kiểu (kiểu cần chuyển đến) được đặt trong cặp ngoặc đơn trước đối tượng (hay biến) cần ép kiểu. Cách này tương đương dùng CType trong VB.
- Cách thứ hai là dùng từ khoá as tương đương dùng TryCast trong VB.
Mã C#
object o1 = 1; int i1 = (int)o1; // dùng cách thứ nhất double o2 = 1; int i2 = o2 as int;// dùng cách thứ hai
Mảng (array), collection, generic
Mảng (array)
Mảng là một danh sách chứa các phần tử cùng kiểu như các số nguyên, chuỗi,…Mỗi phần tử trong mảng được xác định tại một vị trí được gán chỉ số (index). Phần tử ở vị trí đầu tiên sẽ có chỉ số là 0, phần tử cuối cùng trong mảng có n phần tử có chỉ số là n – 1. Khai báo, truy cập (gán giá trị, hiển thị ) các phần tử mảng trong VB dùng dấu ngoặc tròn, dùng ngoặc vuông trong C#.
Cú pháp VB
Dim tên_mảng(chỉ số cao nhất trong mảng) As kiểu_dữ_liệu
Cú pháp C#
kiểu_dữ_liệu[] tên_mảng = new kiểu_dữ_liệu[kích cỡ hay số phần tử trong mảng];
Khác với một số ngôn ngữ họ C như C# hay Java, khai báo mảng trong VB không dùng kích cỡ mảng mà là dùng chỉ số cao nhất có thể có trong mảng. Ví dụ khai báo mảng trong VB chứa 2 số nguyên tên arrInt như sau:
Dim arrInt(1) As Integer
Mảng arrInt chứa hai số nguyên nên phần tử đầu tiên có chỉ số 0, phần tử thứ hai có chỉ số 1 và đây là chỉ số cao nhất nên trong khao báo trên dùng arrInt(1).
Trong khi đó khai báo trong C# như sau:
int[] arrInt = new int [2];
Gán giá trị cho các phần tử trong mảng ta dùng cú pháp VB:
tên_mảng (chỉ số của phần tử) = giá trị
Cú pháp C#:
tên_mảng [chỉ số của phần tử] = giá trị;
Ví dụ gán các giá trị số nguyên cho hai phần tử trong mảng arrInt như sau:
Mã VB:
arrInt (0) = 7 ' Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt (1) = 19 ' Gán 19 cho phần tử thứ hai arrInt (2) = 5 ' lỗi vì mảng chỉ chứa tối đa 2 phần tử
Mã C#:
arrInt [0] = 7; // Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt [1] = 19; // Gán 19 cho phần tử thứ hai arrInt [2] = 5; // lỗi vì mảng chỉ chứa tối đa 2 phần tử
* Chú ý: theo sau mỗi dòng lệnh là dấu ‘ và dòng văn bản, đó là các chú thích trong VB; chú thích trong C# là //.
Để truy cập phần tử trong mảng ta dùng cú pháp VB:
tên_mảng (chỉ số phần tử)
Cú pháp C#:
tên_mảng [chỉ số phần tử];
Khi khai báo mảng chúng ta thường gán cho mảng một kích cỡ nào đó mặc định, nhưng trong thực tế có thể giảm hoặc tăng kích thước ban đầu. Để khai báo lại kích thước mảng và làm mới lại toàn bộ các phần tử trong mảng ta dùng cú pháp trong VB:
ReDim tên_mảng (chỉ số cao nhất cập nhật)
Trong trường hợp chúng ta muốn tăng kích thước mảng đồng thời muốn giữ lại các giá trị đã gán cho các phần tử trong mảng trước đó, chúng ta dùng cú pháp như trên nhưng có thêm từ khoá Preserve, cú pháp:
ReDim Preserve tên_mảng (chỉ số cao nhất cập nhật)
Ví dụ:
Dim arrInt(1) As Integer arrInt (0) = 7 ' Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt (1) = 19 ' Gán 19 cho phần tử thứ hai arrInt (2) = 5 ' lỗi ReDim Preserve arrInt(2) arrInt (2) = 5 ReDim Preserve arrInt(3) ' các phần tử trong arrInt trở thành Nothing
Trong C# không có từ khoá để làm mới lại kích cỡ mảng nhưng chúng ta có thể dùng phương thức tĩnh Resize của lớp Array. Ví dụ với mảng arrInt như sau:
int[] arrInt = new int[2]; arrInt [0] = 7; //Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt [1] = 19; //Gán 19 cho phần tử thứ hai arrInt (2) = 5; // lỗi Array.Resize (ref arrInt, 3); arrInt [2] = 5;
Collection
Cấu trúc mảng thiếu một vài tính năng hữu ích như thêm, xoá, sửa các phần tử của mảng. Điều này được hỗ trợ bởi các collection. Với collection, nếu chúng ta muốn truy cập các phần tử, thay vì thông qua chỉ số như trong mảng, chúng ta sẽ dùng các phương thức như Add, Remove hay Clear. Có thể lặp qua các phần tử trong collection như lặp qua các phần tử trong mảng. Hai collection phổ biến nhất, được giới thiệu từ .NET Framework 1.0, là ArrayList và HashTable (bảng băm).
Một tiện ích khác của collection, như ArrayList, là việc không cần cập nhật lại kích cỡ như mảng, kích cỡ collection sẽ cập nhật tự động sau mỗi lần thêm, xoá phần tử bất kì.
Ví dụ tạo một ArrayList và gán các giá trị số nguyên vào ArrayList này:
Mã VB
Dim arrLst As New ArrayList ()' có từ khoá New, không có kiểu dữ 'liệu và chỉ số arrLst.Add (7) ' thêm phần tử thứ nhất arrLst.Add (19) ' thêm phần tử thứ hai
Mã C#
ArrayList arrLst = new ArrayList (); //có từ khoá New, không có // kiểu dữ liệu và chỉ số arrLst.Add (7); // thêm phần tử thứ nhất arrLst.Add (19); //thêm phần tử thứ hai
Generic
Trở ngại lớn nhất của collection là nó không quan tâm đến kiểu dữ liệu, nghĩa là ta có thể thêm bất kì đối tượng nào vào collection. .NET Framework 2.0 giới thiệu một khái niệm mới gọi là generic, giúp khắc phục điểm yếu và kế thừa những điểm mạnh của collection.
Generic là một template chứa các đoạn mã có thể được dùng trong những hoàn cảnh khác nhau với những kiểu dữ liệu khác nhau. Ví dụ tạo một danh sách theo kiểu generic chứa các số nguyên, giống ArrayList nhưng có ràng buộc kiểu:
Mã VB
Dim arrGn As New List(Of Integer) arrGn.Add(7) arrGn.Add(19)
Mã C#
List<int> arrGn = new List<int>(); arrGn.Add(7); arrGn.Add(19);
Để thêm phần tử vào collection hay generic chúng ta có thể dùng phương thức Add, ngoài ra, .NET còn hỗ trợ một tính năng gọi là collection initializer. Với tính năng này, chúng ta có thể thêm các phần tử vào collection hay generic chỉ bằng một dòng lệnh (thay vì nhiều lệnh Add).
Ví dụ thêm các phần tử vào danh sách generic arrGn:
Mã VB:
Dim arrGn As New List(Of Integer) From {7, 19}
Mã C#:
List<int> arrGn = new List<int>() {7, 19};
Toán tử (operator)
Toán tử gán (assigment operator)
Dùng để gán một giá trị đến một biến. Giá trị này có thể là hằng (như 6 hay “hello”), giá trị của biến khác, kết quả của một biểu thức hay hàm.
Kí hiệu: =
Ví dụ: gán giá trị 6 cho biến x trong VB
Dim x As Integer = 6
Mã C#
int x = 6;
Toán tử số học (arithmetic operator)
Cho phép thực hiện các thao tác tính toán. Gồm:
Ví dụ trong VB
Dim firstNumber As Integer = 100 Dim secondNumber As Single = 23.5 Dim result As Double = 0 result = firstNumber + secondNumber ' Kết quả 123.5 result = firstNumber - secondNumber ' Kết quả 76.5 result = firstNumber * secondNumber ' Kết quả 2350 result = firstNumber / secondNumber ' Kết quả 4.25531914893617 result = firstNumber \ secondNumber ' Kết quả 4 Dim result As Double result = 2 ^ 3 ' Kết quả 8 (2 * 2 * 2) result = 3 ^ 2 ' Kết quả 9 (3 * 3) Dim firstNumber As Integer = 17 Dim secondNumber As Integer = 3 Dim result As Integer = firstNumber Mod secondNumber ' Kết quả 2
* Chú ý: C# không hỗ trợ toán tử \, tuy nhiên, nếu chúng ta chia hai số nguyên, ví dụ lấy 7 chia 3, thì kết quả sẽ là một số nguyên, ví dụ 7 chia 3 là 3. Điều này chúng ta cần chú ý vì sẽ không cho kết quả như mong đợi. C# cũng không hỗ trợ toán tử ^ mà sẽ dùng phương thức Pow của lớp Math thay thế.
Độ ưu tiên của các toán tử trong biểu thức theo thứ tự giảm dần từ trên xuống như sau:
VB hay C# cho phép kết hợp toán tử số học và toán tử gán. Xem bảng dưới đây:
Toán tử so sánh (comparison operator)
Cho phép so sánh hai giá trị, thường dùng trong các biểu thức điều kiện. Kết quả trả về là True hay False. Một số toán tử so sánh phổ biến:
Toán tử cộng chuỗi (concatention operator)
Để kết hợp hai chuỗi (kiểu String) trong VB chúng ta có thể dùng toán tử &, trong C# dùng +. Có thể kết hợp với toán tử gán là += hay &=. Tuy nhiên, để tránh xảy ra một số lỗi không mong đợi, khi kết hợp hai chuỗi chúng ta dùng &.
Ví dụ: khai báo các biến sau:
Mã VB
Dim firstString As String = "Hello" Dim secondString As String = "World" Dim result As String
Mã C#
string firstString = "Hello"; string secondString = "World"; string result;
Kết hợp hai chuỗi trong biến firstString và secondString và lưu kết quả trong biến result có thể viết như sau:
Mã VB
result = firstString & secondString
hoặc
result = firstString result = result & secondString
hoặc
result = firstString result &= secondString
Mã C#
result = firstString + secondString;
hoặc
result = firstString; result = result + secondString;
hoặc
result = firstString; result += secondString;
Trong VB thỉnh thoảng cũng dùng toán tử + để nối hai chuỗi, tuy nhiên, không nên dùng toán tử này (trong VB) vì có thể xảy ra kết quả không như mong đợi như ví dụ sau:
Dim firstNumber As String = "4" Dim secondNumber As Integer = 5 Dim result As String = firstNumber + secondNumber
Kết quả trong result thay vì là chuỗi “45” thì kết quả là 9
Toán tử luận lý (logical operator)
Trả về giá trị True hay False từ việc kết hợp nhiều biểu thức. Một số toán tử
Ví dụ:
Mã VB:
Dim num1 As Integer = 3 Dim num2 As Integer = 7 num1 = 3 And num2 = 7 ' True num1 = 2 And num2 = 7 ' False num1 = 3 Or num2 = 11 ' True Not num1 = 5 ' True num1 = 2 AndAlso num2 = 7 ' trả về False vì num1 khác 2 và không ' cần kiểm tra biểu thức num2 = 7
Mã C#:
int num1 = 3; int num2 = 7; num1 == 3 & num2 == 7 // true num1 == 2 & num2 == 7 // false num1 == 3 | num2 == 11 // true !(num1 == 5) // true num1 == 2 && num2 == 7 //trả về false vì num1 khác 2 và không //cần kiểm tra biểu thức num2 = 7
Các lệnh điều kiện (conditional statement)
Khi viết code, chúng ta hay gặp những tình huống phải đưa ra những hành động khác nhau trong những điều kiện khác nhau. Để làm điều này, chúng ta sử dụng các lệnh điều kiện (conditional statements).
Lệnh điều kiện trong VB gồm lệnh If và Select Case; trong C# là if và switch. Lệnh If có các phiên bản sau:
Lệnh If
VB
If điều kiện Then khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay True) End If
C#
if (điều kiện){ khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) }
Ví dụ:
Mã VB:
If tuoi < 18 Then thongbao = "Ban chua du tuoi" End If
Mã C#:
if tuoi < 18){ thongbao = "Ban chua du tuoi"; }
Lệnh If…Else
VB
If điều kiện Then khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) Else khốí lệnh sẽ thực thi nếu điều kiện là sai (hay false) End If
C#
if (điều kiện){ khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) } else { khốí lệnh sẽ thực thi nếu điều kiện là sai (hay false) }
Ví dụ:
Mã VB
If tuoi < 18 Then thongbao = "Ban chua du tuoi" Else thongbao = "Chao mung ban den voi website chung toi!" End If
Mã C#
if (tuoi < 18){ thongbao = "Ban chua du tuoi"; } else { thongbao = "Chao mung ban den voi website chung toi!"; }
Lệnh If…ElseIf…Else
VB
If điều kiện 1 Then khốí lệnh sẽ thực thi nếu điều kiện 1 là đúng (hay true) ElseIf điều kiện 2 Then khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là đúng (hay true) Else khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là sai (hay false) End If
C#
if (điều kiện 1){ khốí lệnh sẽ thực thi nếu điều kiện 1 là đúng (hay true) } else if (điều kiện 2){ khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là đúng (hay true) } else { khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là sai (hay false) }
Ví dụ:
Mã VB
If time < 10 Then greeting = "Good morning" ElseIf time < 20 greeting = "Good day" Else greeting = "Good evening" End If
Mã C#
if (time < 10){ greeting = "Good morning"; } else if (time < 20){ greeting = "Good day"; } else{ greeting = "Good evening"; }
Cũng là lệnh điều kiện giống If dùng để đưa ra những hành động khác nhau trong những điều kiện khác nhau, chúng ta có thể dùng Select Case trong VB hay switch trong C#.
Cú pháp Select Case:
Select Case bieu_thuc Case n khối lệnh Case m: khối lệnh Case Else khối lệnh mặc định End Select
Ví dụ:
Dim today As DateTime = DateTime.Now Dim discountPercentage As Double = 0 Select Case today.DayOfWeek Case DayOfWeek.Monday discountPercentage = 40 Case DayOfWeek.Tuesday discountPercentage = 30 Case DayOfWeek.Wednesday discountPercentage = 20 Case DayOfWeek.Thursday discountPercentage = 10 Case Else discountPercentage = 0 End Select
Cú pháp switch:
switch (bieu_thuc){ case n: khối lệnh break; case m: khối lệnh break; default: khối lệnh mặc định break; }
Ví dụ:
DateTime today = DateTime.Now; double discountPercentage = 0; switch (today.DayOfWeek) { case DayOfWeek.Monday: discountPercentage = 40; break; case DayOfWeek.Tuesday: discountPercentage = 30; break; case DayOfWeek.Wednesday: discountPercentage = 20; break; case DayOfWeek.Thursday: discountPercentage = 10; break; default: discountPercentage = 0; break; }
Lệnh lặp (loop statement)
Trong lập trình, có những lệnh hay khối lệnh được lặp lại nhiều lần. Thay vì viết các lệnh hay khối lệnh này nhiều lần, chúng ta có thể dùng các lệnh lặp.
Trong VB có các lệnh lặp là For, For/In, While và Do/While.
Lệnh For
Dùng để lặp theo một số lần xác định cho trước, ví dụ thực hiện lệnh xuất dòng chữ Hello 5 lần.
Cú pháp lệnh For trong VB:
For Biến_đếm [ As Kiểu_dữ_liệu ] = Bắt_đầu To Kết_thúc [Step Bước_lặp] ' Đoạn mã được lặp Next [Biến_đếm ]
Những thành phần chứa trong [ ] là tuỳ chọn (có hoặc không).
Cú pháp lệnh For trong C#:
for (điều kiện bắt đầu lặp; điều kiện kết thúc lặp; bước lặp) { // Đoạn mã được lặp }
Ví dụ hiển thị các số nguyên từ 1 đến 10 trên 10 hàng trong một Label control:
Mã VB:
For loopCount As Integer = 1 To 10 Label1.Text &= loopCount.ToString() & "
" Next
Mã C#:
for (int loopCount = 1; loopCount <= 10; loopCount ++) { Label1.Text += loopCount.ToString() + "
"; }
Hiển thị các số chẵn trong dãy số nguyên từ 0 đến 10
Mã VB:
For loopCount As Integer = 0 To 10 Step 2 Label1.Text &= loopCount.ToString() & "
" Next
Mã C#:
for (int loopCount = 0; loopCount <= 10; loopCount = loopCount + 2) { Label1.Text += loopCount.ToString() + "
"; }
Hiển thị các phần tử trong mảng:
Mã VB:
Dim arrInt(2) As Integer arrInt (0) = 7 arrInt (1) = 19 arrInt (2) = 5 For loopCount As Integer = 0 To arrInt.Length - 1 Label1.Text &= arrInt(loopCount).ToString() & "
" Next
Mã C#:
int arrInt[] = new int[3]; arrInt [0] = 7; arrInt [1] = 19; arrInt [2] = 5; for (int loopCount = 0; loopCount < arrInt.Length; loopCount ++) { Label1.Text += arrInt[loopCount].ToString() + "
"; }
Lệnh For Each
Dùng để lặp qua các phần tử trong collection hay generic. Ví dụ:
Mã VB:
Dim arrGn As New List(Of Integer) From {7, 19} For Each item As Integer In arrGn Label1.Text &= item.ToString() & "
" Next
Mã C#:
List<int> arrGn = new List<int>() {7, 19}; foreach (int item in arrGn) { Label1.Text += item.ToString() + "
"; }
Lệnh While
Khác với For, lệnh While sẽ lặp theo một điều kiện nào đó. Chừng nào điều kiện còn đúng thì lệnh lặp sẽ vẫn thực thi.
Cú pháp trong VB:
While dieu_kien Đoạn mã được lặp End While
Cú pháp trong C#:
while (dieu_kien) { Đoạn mã được lặp }
Ví dụ: lệnh lặp sau sẽ còn thực thi chừng nào điều kiện i < 10 còn đúng, biến i sẽ tăng 1 đơn vị sau mỗi lần lặp
Mã VB:
Dim i As Integer = 0 While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 End While
Mã C#:
int i = 0; while (i < 10) { Label1.Text += "The number is " + i.ToString(); i = i + 1; // hay i++; }
Lệnh Do While, Do Until
Trong VB còn có lệnh Do While Do Until giống lệnh While là lặp khi điều kiện là đúng
Cú pháp VB:
Do {While | Until} dieu_kien Đoạn mã được lặp Loop
Ví dụ:
Mã VB
Dim i As Integer = 0 Do While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 Loop
Mã C#
int i = 0; do { Label1.Text += "The number is " + i.ToString(); i = i + 1; } while (i < 10);
Lệnh Do..Loop {While | Until}
Giống lệnh Do While hay Do Until nhưng Do..Loop thực hiện lệnh ít nhất một lần.
Cú pháp VB:
Do Đoạn mã được lặp Loop {While | Until} dieu_kien
Cú pháp C#:
do { Đoạn mã được lặp } while (dieu_kien);
Xét ví dụ sau để phân biệt While và Do..Loop (hay while và do…while):
Đoạn mã sau sẽ không thực thi vì i = 11 >10
Mã VB
Dim i As Integer = 11 While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 End While
Mã C#
int i = 11; while (i < 10) { Label1.Text += "The number is " + i.ToString(); i = i + 1; }
Đoạn mã sau sẽ thực thi và kết quả là The number is 11
Mã VB
Dim i As Integer = 11 Do Label1.Text &= "The number is " & i.ToString() i = i + 1 Loop While i < 10
Mã C#
int i = 11; do { Label1.Text += "The number is " + i.ToString(); i = i + 1; } while (i < 10);
Lệnh thoát vòng lặp
Có thể thoát khỏi vòng lặp While, Do hay For bằng lệnh Exit Do, Exit Do hay Exit For (break trong C#). Ví dụ: vòng lặp sau sẽ thoát khi i = 5, tức là chỉ xuất các giá trị từ 1 đến 4
Mã VB
For i As Integer = 1 To 10 If i = 5 Then Exit For End If Label1.Text &= i.ToString() & "
" Next
Mã C#
for (int i = 1; i <= 10; i++) { if (i == 5) { break; } Label1.Text += i.ToString() + "
"; }
Có thể bỏ qua một lần lặp để chuyển qua lần lặp kế tiếp bằng lệnh Continue While, Continue Do hay Continue For (continue trong C#). Ví dụ xuất từ 1 đến 10 nhưng bỏ số 5:
Mã VB
For i As Integer = 1 To 10 If i = 5 Then Continue For End If Label1.Text &= i.ToString() & "
" Next
Mã C#
for (int i = 1; i <= 10; i++) { if (i == 5) { continue; } Label1.Text += i.ToString() + "
"; }
Các phương thức (methods)
Dùng để chứa các đoạn mã có thể được sử dụng nhiều lần, tại bất kì vị trí nào.
Phương thức trong VB hay C# có hai dạng là Function và Sub (chúng giống như khái niệm hàm hay thủ tục trong C).
Cú pháp Function trong VB:
PublicFunction Tên_Function ([Danh sách tham số]) As Kiểu_dữ_liệu ' Mã thực thi Return Giá_trị_trả_về End Function
Cú pháp Function trong C#:
public Kiểu_dữ_liệu Tên_Function ([Danh sách tham số]) { //Mã thực thi return Giá_trị_trả_về; }
Cú pháp Sub trong VB
Public Sub Tên_Sub ([Danh sách tham số]) ' Mã thực thi End Sub
Cú pháp Sub trong C#
publicvoid Tên_Sub ([Danh sách tham số]) { Mã thực thi }
Sự khác biệt giữa Function và Sub là Function có giá trị trả về (từ khoá Return) có kiểu dữ liệu là Kiểu_dữ_liệu của Function. Từ khoá Public định nghĩa phạm vi của phương thức. Trong Function hay trong Sub có chứa danh sách tham số hoặc không.
Ví dụ về Function tính tổng hai số nguyên
Mã VB
Public Function Add(a As Integer, b As Integer) As Integer Return a + b End Function
Mã C#
public int Add(int a, int b) { return a + b; }
Ví dụ Sub hiển thị một thông điệp
Mã VB
Public Sub DisplaylMessage(msg As String) MessageBox.Show(msg) End Sub
Mã C#
public void DisplaylMessage(string msg) { MessageBox.Show(msg); }
Trong Function Add có hai tham số là a và b; nó có kiểu dữ liệu trả về là Integer và giá trị trả về là tổng a và b thông qua từ khoá Return có kiểu là Integer. Sub DisplayMessage có một tham số là msg; nó không có kiểu dữ liệu và giá trị trả về.
Trong ngôn ngữ lập trình hướng đối tượng như C# hay VB, Function hay Sub có thể được gọi bằng một tên chung là phương thức (method).
Các tham số trong Function hay Sub có hai hình thức là tham trị dùng từ khoá ByVal (hoặc không) và tham chiếu dùng tử khoá ByRef. Mặc định là truyền tham trị.
Khi tham số truyền tham trị, một bản sao được tạo ra. Bất kì sự thay đổi đều xảy ra trên bản sao và bản sao này sẽ bị huỷ khi phương thức ngừng thực thi do đó sẽ không ảnh hưởng đến bản gốc. Ngược lại, khi tham số được truyền theo kiểu tham chiếu thì mọi thay đổi sẽ diễn ra trên bản gốc, do đó, khi phương thức kết thúc thì bản gốc cũng bị thay đổi.
Ví dụ:
Public Sub ByValDemo(someValue As Integer) 'truyền tham trị someValue = someValue + 20 End Sub Public Sub ByRefDemo(ByRef someValue As Integer) 'truyền tham chiếu someValue = someValue + 20 End Sub Dim x As Integer = 0 ByValDemo(x) ' một bản sao của x được tạo ra và được gán giá trị 20 Label1.Text = x.ToString() ' x = 0 vì bản sao bị huỷ và bản gốc ' không thay đổi Dim y As Integer = 0 ByRefDemo(y) ' y = 20 Label1.Text = y.ToString() ' y = 20 vì bản gốc bị thay đổi đến 20
Trong C# dùng từ khoá ref có chức năng tương tự ByRef, chỉ khác là chúng ta phải dùng từ khoá ref trong cả lệnh gọi Function hay Sub. Ví dụ:
public void ByRefDemo(ref int someValue) { someValue = someValue + 20; } int y = 0; ByRefDemo(ref y); // y = 20
Thực hành
Trong phần thực hành này, chúng ta sẽ tạo ra một ứng dụng tên Calculator thực hiện các phép toán đơn giản như +, -, *, /.
Ứng dụng Calculator
- Trong thư mục Demos, tạo trang mới tên CalculatorDemo.aspx, chú ý chọn Place code in separate file và bỏ chọn Select master page.
- Chuyển trang sang chế độ Design, đặt con trỏ trong vùng có viền, chọn Table > Insert Table với 3 dòng 3 cột. Kết hợp 3 ô đầu tiên của Table bằng cách bôi đen 3 ô này và chọn Table > Modify > Merge Cells.
- Thêm các controls với ID và các thuộc tính như sau:
-
- Giao diện sẽ trông như sau:
- Trong thư mục App_Code thêm một lớp mới tên Calculator bằng cách nhấp chuột phải và chọn Add > Add New Item > Class và đặt tên là Calculator.vb và nhấn Add sẽ đến giao diện như sau:
- Bổ sung code như sau:
- Trở lại trang CalculatorDemo.aspx trong thư mục Demos ở chế độ Desgin, nhấp đôi chuột vào button Calculate sẽ đến giao diện code như sau:
- Thêm code vào Sub CalculateButton_Click như sau:
- Lưu tất cả, chọn trang CalculatorDemo.aspx và Ctrl + F5.
Namespace (không gian tên)
Namespace là một bộ chứa (container) dùng để chứa một số lượng lớn các chức năng ( thường là lớp) trong .NET Framework hay trong chương trình của bạn và chống lại tình trạng xung đột trong trường hợp chia sẻ các thành phần (lớp) có cùng tên.
Có thể truy cập các thành phần trong namspace thông bằng cú pháp:
tên_namespace.thành_phần_cần_truy_cập
Ví dụ chúng ta thấy một khai báo trong một trang aspx như sau:
Mã VB
Partial Class Demos_CalculatorDemo Inherits System.Web.UI.Page
Mã C#
public partial class Demos_CalculatorDemo : System.Web.UI.Page
Ta thấy lớp Demos_CalculatorDemo thừa kế từ lớp Page và lớp này được chứa trong namespace System.Web.UI.
Các kiểu dữ liệu cũng được chứa trong namespace, ví dụ kiểu Double chứa trong namespace System nên khi truy cập Double ta thường dùng System.Double. Hay control Button được chứa trong namespace System.Web.UI.WebControls.
Thực hành tạo namespace (VB)
- Mở file Calculator.vb đã tạo và tạo một namspace tên là NgocMinh.VD chứa lớp Calculator. Bổ sung đoạn mã như sau:
- Lúc này lớp Calculator được chứa trong namespace NgocMinh.VD nên khi mở trang code VB của trang CaculatorDemo.aspx (tức mở file CalculatorDemo.aspx.vb) sẽ bị lỗi như sau:
- Lỗi trên do trình biên dịch không nhận ra lớp Calculator, để khắc phục lỗi trên chúng ta phải khai báo namespace NgocMinh.VD bằng lệnh imports ở dòng đầu tiên như sau:
- Lưu, chọn trang Caculator.aspx và Ctrl + F5. Kết quả giống phần thực hành trên.
Chú thích (comment)
Comment là nội dung không được thực thi nhằm giải thích các đoạn mã giúp người khác có thể đọc code dễ dàng hơn hoặc có thể giúp ích trong quá trình sửa lỗi chương trình.
Chú thích trong VB bắt đầu bằng dấu nháy đơn, trong C# dùng dấu // để chú thích một dòng và dùng /*…*/ để chú thích nhiều dòng . Ví dụ: chú thích
Mã VB
' khai bao bien kieu Integer ' và gan gia tri là 5 Dim x As Integer = 5
Mã C#
// khai bao bien kieu Integer // và gan gia tri là 5 int x = 5; hay /* khai bao bien kieu Integer và gan gia tri là 5 */ int x = 5;
Chú thích XML có thể được thực hiện bằng cách thêm các phần tử XML. Chú thích XML bắt đầu bằng ba dấu nháy đơn ”’
Ví dụ Function Add có thể chú thích XML như sau (tương tự các Function khác): đặt con trỏ chuột phía trên Function Add và gõ ba dấu nháy đơn liên tiếp sẽ xuất hiện các thẻ XML như  hay <param>. Các thẻ XML cũng như các thẻ HTML có thẻ bắt đầu, như , và thẻ kết thúc, như .
Bổ sung các ghi chú như sau:
Điểm thú vị khi chú thích XML sẽ hiển thị khi chúng ta sử dụng Add trong file CalculatorDemo.aspx.vb như sau:
Cơ bản về hướng đối tượng
Mọi thứ trong .NET Framework đều là đối tượng (object), từ những kiểu dữ liệu đơn giản như Integer đến những thứ phức tạp như DropDownList control,…
Object (đối tượng)
Object là khái niệm cơ bản trong lập trình hướng đối tượng (object oriented programming). Đó là một cấu trúc đóng gói dữ liệu và chức năng như một đơn vị duy nhất và chỉ có thể truy cập đối tượng thông qua giao diện của nó như thuộc tính, phương thức. Quá trình tạo một đối tượng gọi là quá trình thực thể hoá (instantiating) bằng từ khoá New (hay new trong C#). Ví dụ tạo các đối tượng từ các lớp Calculator hay Integer như sau:
Mã VB
Dim myCalculator As Calculator = New Calculator() Dim age As Integer = New Integer()
Mã C#
Calculator myCalculator = new Calculator(); int age = new int();
myCalculator và age được gọi là các instance (thực thể hay thể hiện) hay phổ biến hơn gọi là các object (đối tượng).
Trước khi có object cần có một định nghĩa chi tiết về object thông qua class.
Class (lớp)
Class giống như một bản kế hoạch chi tiết cho object. Trong ví dụ trước, chúng ta đã định nghĩa class Calculator và từ lớp này có thể tạo ra nhiều thực thể (instance) hay đối tượng, ví dụ như myCalculator (ví dụ trên). Cú pháp tạo một class:
VB
Public Class Tên_class ' các thành phần trong class End Class
C#
public class Tên_class { // các thành phần trong class }
Các thành phần trong class gồm các trường (fields), thuộc tính (properties), phương thức (methods) và phương thức constructor.
Field (trường)
Là các đặc điểm riêng của đối tượng, ví dụ đối tượng SinhVien có các đặc điểm riêng là firstName, lastName, sex,…Định nghĩa field giống như định nghĩa biến theo cú pháp sau:
VB
Phạm_vi_truy_cập Tên_field As Kiểu_dữ_liệu
C#
Phạm_vi_truy_cập Kiểu_dữ_liệu Tên_field;
Phạm_vi_truy_cập là phạm vi truy cập của field (sẽ được đề cập phần tiếp theo), có thể là Private, Public, Protected hay Friend. Ví dụ:
Mã VB
Public Class Person Private firstName As String ' trường firstName với phạm vi là Private End Class
Mã C#
public class Person { private string firstName; //trường firstName với phạm vi là private }
Thông thường các field là các đặc điểm (hay dữ liệu) riêng tư của đối tượng và không thể truy cập trực tiếp (phạm vi truy cập Private). Do đó, để truy cập các fields chúng ta dùng các thuộc tính (properties).
Property (thuộc tính)
Property có thể hiểu là giao diện để có thể truy cập các trường (fields). Điều này liên quan đến một khái niệm cốt lõi trong mô hình hướng đối tượng gọi là tính đóng gói (encapsulation) hay là khả năng ẩn đi những cái phức tạp hay quan trọng của đối tượng, chỉ đưa ra giao diện cần thiết cho người dùng. Có thể hiểu khái niệm này giống như máy ATM, người dùng chỉ có thể thấy được giao diện để nhập thông tin và nhận tiền còn quá trình xử lý, cấu tạo bên trong thì không cần biết.
Trong VB, thuộc tính có thể khai báo giống như field, ngoại trừ có từ khoá Property:
VB
Public Property Tên_thuộc_tính As Kiểu_dữ_liệu
Trong C# không dùng Property
C#
public Kiểu_dữ_liệu Tên_thuộc_tính {get; set;}
Có thể dùng khối lệnh Get (còn gọi là getter) để lấy dữ liệu từ các trường và khối lệnh Set (còn gọi là setter) để gán giá trị cho trường. Cú pháp:
VB
Phạm_vi_truy_cập Property Tên_thuộc_tính () As Kiểu_dữ_liệu Get ' trả về giá trị của một trường nào đó với Return End Get Set (value As String) ' value phải được khai báo như là tham số của Set ' gán giá trị value cho trường End Set End Property
C#
Phạm_vi_truy_cập Kiểu_dữ_liệu Tên_thuộc_tính { get { // trả về giá trị của một trường nào đó với Return } set { // value không cần khai báo // gán giá trị value cho trường } }
Ví dụ lấy giá trị và gán giá trị cho trường firstName của class Person:
Mã VB
Public Class Person Private firstName As String Public Property FirstName() As String Get Return firstName End Get Set(value As String) firstName = value End Set End Property End Class
Mã C#
public class Person { private string firstName; public string FirstName { get { return firstName; } set { firstName = value; } } }
Chúng ta không thể truy cập trực tiếp đến field firstName mà phải thông qua thuộc tính FirstName. Cụ thể:
Mã VB
' tạo một instance của đối tượng Person Dim myPerson As Person = New Person() ' Gán giá trị cho firstName thông qua FirstName myPerson.FirstName = "Ngoc Minh" ' lấy giá trị firstName Label1.Text = myPerson.FirstName
Mã C#
// Tạo một instance của đối tượng Person Person myPerson = new Person(); // Gán giá trị cho firstName thông qua FirstName myPerson.FirstName = "Ngoc Minh"; // lấy giá trị firstName Label1.Text = myPerson.FirstName;
Thuộc tính chỉ đọc (read only) và thuộc tính chỉ ghi (write only)
* Trong VB có thể tạo ra các thuộc tính chỉ đọc (read only) hay chỉ ghi (write only) theo cú pháp:
Thuộc tính chỉ đọc với từ khoá ReadOnly và khối Get
Phạm_vi_truy_cập ReadOnly Property Tên_thuộc_tính () As Kiểu_dữ_liệu Get ' trả về giá trị của một trường nào đó với Return End Get End Property
Thuộc tính chỉ ghi với từ khoá WriteOnly và khối Set
Phạm_vi_truy_cập WriteOnly Property Tên_thuộc_tính () As Kiểu_dữ_liệu Set (value As String) ' gán giá trị cho trường End Set End Property
* Trong C#, việc tạo thuộc tính chỉ đọc đơn giản chỉ là bỏ khối lệnh set, tạo thuộc tính chỉ ghi chỉ cần bỏ khối lệnh get.
Method (phương thức)
Nếu field hay property là đặc điểm của đối tượng thì method là hành vi hay chức năng của đối tượng. Ví dụ đối tượng Person có các đặc điểm là firstName, lastName, dateOfBirth và phương thức là Talk () để giới thiệu bản thân.
Định nghĩa method trong class giống định nghĩa Sub hay Function. Ví dụ:
Mã VB
Public Class Person Public Sub Talk() ' code thực thi phương thức Talk End Sub End Class
Mã C#
public class Person { public void Talk() { // code thực thi phương thức Talk } }
Constructor (phương thức khởi tạo)
Là một phương thức đặc biệt, thực thi ngay khi chúng ta tạo một instance cho một object và theo sau từ khoá New. Phương thức constructor có tên trùng với tên class. Ví dụ tạo instance của đối tượng Calculator như sau:
Mã VB
Dim myCalculator As Calculator = New Calculator()
Mã C#
Calculator myCalculator = new Calculator();
Nếu chúng ta không định nghĩa constructor trong class thì trình biên dịch sẽ tạo một constructor mặc định. Mặc định, trong VB phương thức construtor trong class tên là New không có tham số và không có giá trị trả về, trong C# phương thức contructor có tên trùng với tên lớp, không có tham số và không có giá trị trả về. Cú pháp:
VB
Public Class Tên_class Public Sub New() End Sub End Class
C#
public class Tên_class { public Tên_class() { } }
Quá tải constructor
Bên cạnh constructor mặc định, chúng ta có thể định nghĩa nhiều constructor trong class và các phương thức constructor này phải có danh sách tham số khác nhau . Ví dụ class Person có hai constructor, một constructor không có tham số và một constructor có một tham số trong danh sách tham số, có thể định nghĩa như sau:
Mã VB
Public Class Person Private firstName As String ' constructor không có tham số Public Sub New () firstName = "Minh" End Sub ' constructor có tham số Public Sub New (fName As String) firstName = fName End Sub End Class
Mã C#
public class Person { private string firstName; // constructor không có tham số public Person () { firstName = "Minh"; } // constructor có tham số public Person (string fName) { firstName = fName; } }
Với cách định nghĩa class Person như trên, chúng ta có thể có hai cách (hai phiên bản) tạo instance cho Person:
Mã VB
Dim myPerson As Person = New Person() Dim myPerson As Person = New Person("Minh")
Mã C#
Person myPerson = new Person(); Person myPerson = new Person("Minh");
.NET cũng cung cấp cho bạn một cách khác để tạo object và khởi tạo giá trị cho thuộc tính. Cách này gọi là object initializer.
Trong VB, ví dụ class Person có thuộc tính FirstName:
Public Class Person Public Property FirstName As String End Class
Tạo instance của Person và khởi tạo thuộc tính FirstName với từ khoá With:
Dim myPerson As New Person() With {.FirstName = "Minh" }
Chú ý: trong VB có từ khoá With và dấu . trước thuộc tính FirstName.
Trong C#, ví dụ class Person có thuộc tính FirstName:
public class Person { public string FirstName {get;set;} }
Tạo instance của Person và khởi tạo thuộc tính FirstName:
Person myPerson = new Person(){FirstName = "Minh" };
Chú ý: trong C# không có từ khoá With và dấu . trước thuộc tính FirstName.
Inheritance (thừa kế)
Một trong những khái niệm quan trọng và rất mạnh của mô hình hướng đối tượng, bên cạnh tính đóng gói đã đề cập ở trên, là khái niệm thừa kế. Thừa kế nhằm tận dụng dữ liệu và chức năng có sẵn để phát triển, mở rộng ứng dụng ở mức cao hơn. Ví dụ các lớp Student hay Employee có thể kế thừa từ lớp Person vì chúng đều cần các đặc điểm như firstName, lastName hay phương Talk()…
Tuỳ theo phạm vi truy cập (Private, Public, Protected, Friend) mà các thuộc tính hay phương thức của lớp cha sẽ được kế thừa từ lớp con. Một lớp muốn thừa kế một lớp khác phải dùng từ khoá inherits (trong VB) hay dấu hai : (trong C#) theo cú pháp:
VB
Public Class Tên_lớp_con Inherits Tên_lớp_cha ' mã End Class
C#
public class Tên_lớp_con : Tên_lớp_cha { // mã }
Ví dụ lớp Student thừa kế từ lớp Person như sau:
Mã VB
Public Class Student Inherits Person ' mã End Class
C#
public class Student : Person { // mã }
Mỗi trang ASPX được tạo ra thừa kế từ lớp System.Web.UI.Page, lớp này được thừa kế từ lớp TemplateControl được thừa kế từ lớp Control và Control thừa kế từ lớp Object. Ví dụ ta có trang MyWebPage.aspx sẽ có cây thừa kế như sau:
Lớp TemplateControl ở trên gọi là lớp cơ sở (base class), là lớp không thể được thực thể hoá, nghĩa là không thể dùng từ khoá New để tạo ra một instance mới.
Polymophism (đa hình)
Các phương thức trong lớp cha có thể có thể được thừa kế từ lớp con nếu phạm vi truy cập của nó là Public hay Protected. Mặc khác, chúng ta có thể định nghĩa lại các phương thức được thừa kế nhờ một tính năng thú vị khác trong mô hình hướng đối tượng là tính đa hình (polymophism). Ví dụ phương thức Talk() của lớp Person có thể được thừa kế và định nghĩa lại trong lớp Student. Muốn vậy, khi định nghĩa phương thức Talk trong Person phải có từ khoá Overridable (trong VB) hay virtual (trong C#) và phương thức Talk trong Student được định nghĩa lại với từ khoá Overrides (trong VB) hay override (trong C#), cụ thể lớp Person:
Mã VB
' Lớp Person Public Class Person Public Overridable Sub Talk() 'Code thực thi End Sub End Class ' Lớp Student Public Class Student Inherits Person Public Overrides Sub Talk(msg As String) 'Code thực thi End Sub End Class
Mã C#
// Lớp Person public class Person { public virtual void Talk() { // Code thực thi } } // Lớp Student public class Student : Person { public override void Talk(msg As String) { // Code thực thi } }
Phạm vi truy cập
Các phần trên chúng ta đã đề cập đến phạm vi truy cập của các thuộc tính hay phương thức của đối tượng. Cụ thể có 4 phạm vi truy cập thể hiện qua 4 từ khoá là Public, Private, Protected và Friend (internal trong C#), có thể được mô tả như sau:
Ví dụ:
Mã VB
Public Class A Public x As Integer Private y As String Protected i As Double Protected Friend j As Date End Class Public Class B Inherits A Public Sub Init() x = 5 ' x kế thừa từ A i = 4.5 ' i kế thừa từ A j = Date.Now 'j kế thừa từ A y = "Hello" ' phát sinh lỗi vì y là Private End Sub End Class Public Class C Public Sub Test() Dim myB As New B() myB.x ' x kế thừa từ A và có phạm vi Public myB.Init()'phương thức Public của B End Sub End Class
Mã C#
public class A { public int x; private string y; protected double i; protected internal date j; } public class B : A { public void Init() { x = 5; // x kế thừa từ A i = 4.5; // i kế thừa từ A j = Date.Now; // j kế thừa từ A y = "Hello" ;// phát sinh lỗi vì y là Private } } public class C { public void Test() { B myB = new B(); myB.x; // x kế thừa từ A và có phạm vi Public myB.Init(); //phương thức Public của B } }
Sự kiện (event)
ASP.NET là môi trường hướng sự kiện, nghĩa là các đoạn mã sẽ được thực thi dựa trên các sự kiện xuất hiện trong ứng dụng. Các sự kiện được phát sinh bởi đối tượng nào đó và được xử lí (handle) bởi đối tượng khác. Để xử lí các sự kiện, chúng ta cần bộ xử lí sự kiện (event handler). Vi dụ khi chúng ta nhấp đôi chuột vào một đối tượng Button trong trang aspx ở chế độ Desgin, Button sẽ phát sinh sự kiện Click và VS sẽ tạo ra bộ xử lí sự kiện Click với đoạn mã sau:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click End Sub
Để xem một đối tượng control có thể có sự kiện gì trong chế độ Design, chúng ta có thể nhấp vào nút có hình tia chớp trong hộp Properties của control tương ứng, như hình:
Xử lí ngoại lệ (exception handling)
Khi lập trình, chúng ta thường gặp một số kiểu lỗi sau:
- Lỗi cú pháp (syntax errors): gõ sai chính tả, thiếu từ khoá, mã không chính xác. Thường có một số dấu hiệu trong VS để cảnh báo đoạn code của chúng ta bị lỗi cú pháp, thường là các đường gợn sóng xanh như hình dưới:
- Lỗi logic (logical errors): thường là do thuật toán sai; chương trình vẫn chạy bình thường nhưng tạo ra các kết quả không mong muốn hay mong đợi. Ví dụ đoạn code sau nhầm lẫn vị trí giữa hai biến toAddress và fromAddress, và lỗi này sẽ khó phát hiện trong chương trình có hàng trăm dòng mã:
Mã VB
Dim fromAddress As String = "you@example.com" Dim toAddress As String = EmailAddress.Text myMessage.From = New MailAddress(toAddress) myMessage.To.Add(New MailAddress(fromAddress))
Mã C#
string fromAddress = "you@example.com"; string toAddress = EmailAddress.Text; myMessage.From = new MailAddress(toAddress); myMessage.To.Add(new MailAddress(fromAddress));
- Lỗi Runtime (Runtime errors): xuất hiện trong thời gian chạy chương trình. Lỗi nay thường khó phát hiện và cần một chiến lược để xử lí.
Phát hiện và xử lí ngoại lệ (catching and handling exceptions)
Ngoại lệ là các lỗi không như mong đợi và khi chúng xảy ra người dùng sẽ nhận được một thông điệp. Lớp ngoại lệ trong .NET thừa kế từ lớp cơ sở (base class) System.Exception.
Kĩ thuật phổ biến để phát hiện và xử lí các ngoại lệ là dùng lệnh khối lệnh Try..Catch..Finally theo cú pháp:
VB
Try khối lệnh để kiểm tra Catch err As Exception Khối lệnh sẽ thực thi khi phát hiện lỗi từ Try Finally Khối lệnh sẽ thực thi mà không quan tâm kết quả từ Try/Catch End Try
C#
try { khối lệnh để kiểm tra } catch (Exception err) { Khối lệnh sẽ thực thi khi phát hiện lỗi từ Try } finally { Khối lệnh sẽ thực thi mà không quan tâm kết quả từ Try/Catch }
Ví dụ:
Mã VB
Dim userMessage As String = String.Empty Try mySmtpClient.Send(myMessage) userMessage = "Message sent" Catch ex As Exception userMessage = "An unknown error occurred." Finally Message.Text = userMessage End Try
Mã C#
string userMessage = string.Empty; try { mySmtpClient.Send(myMessage); userMessage = "Message sent"; } catch (Exception err) { userMessage = "An unknown error occurred."; } finally { Message.Text = userMessage; }
Thực hành dưới đây minh hoạ trong quá trình gửi mail có thể phát sinh lỗi (chẳng hạn như Mail Server bị hỏng) thì một thông báo sẽ phát sinh để tránh hỏng toàn bộ ứng dụng.
Thực hành phát hiện và xử lí ngoại lệ (VB)
- Tạo một trang tên ExceptionHandling.aspx trong thư mục Demos, chọn template là MyBasePage (do chúng ta tạo ra trong chương trước) và thiết lập thuộc tính Title là Exception Handling Demo.
- Thêm một Label đến vùng cpMainContent và thiết lập thuộc tính ID của nó là Message
- Chuyển trang đến chế độ Design và chọn sự kiện Load của trang bằng cách nhấp đôi chuột vào một vị trí bất kì trong trang. Bổ sung thêm dòng mã Imports System.Net.Mail vào đầu file code VB (ExceptionHandling.aspx.vb):
- Thêm code vào Sub Page_Load như sau:
- Lưu, chọn trang ExceptionHandling.aspx và Ctrl + F5 sẽ xuất hiện lỗi sau:
- Để tránh lỗi này, trở lại file ExceptionHandling.aspx.vb và dùng khối Try..Catch cho đoạn mã như sau:
- Lưu, chọn trang ExceptionHandling.aspxvà Ctrl + F5 sẽ như sau:
Tìm và xử lí lỗi (debugging)
Debugging là quá trình tìm và xử lí lỗi trong ứng dụng. Quá trình tìm và xử lí lỗi là phức tạp, đòi hỏi nhiều kĩ thuật. VS cung cấp cho chúng ta nhiều công cụ để debugging được dễ dàng hơn.
Thiết lập điểm dừng (breakpoint)
Một kĩ thuật phổ biến trong debugging là thiết lập điểm dừng. Bằng cách này, VS sẽ dừng thực thi ứng dụng ngay tại dòng code mà bạn thiết lập breakpoint. Để làm điều này, chúng ta chỉ cần chọn dòng code và nhấn F9 (hay nhấp chuột vào dấu chấm lớn ở lề trái của dòng code hay vào Debug > Toggle Breakpoint). Để xoá tất cả các breakpoint trên toàn website, ta nhấn Ctrl + Shift + F9. Để rõ hơn về kĩ thuật breakpoint, chúng ta sẽ thực hiện bài thực hành đơn giản dưới đây trên trình duyệt Chrome.
Thực hành thiết lập breakpoint (VB)
- Mở file CalculatorDemo.aspx.vb trong thư mục Demos
- Chọn dòng mã đầu tiên trong bộ xử lí sự kiện CalculateButton_Click (kiểm tra chiều dài hai textbox). Nhấn F9 để thiết lập breakpoint. Dòng mã thiết lập breakpoint sẽ có màu đỏ như sau:
- Nhấn F5 (lưu ý là F5 chứ không phải là Ctrl + F5) hay vào Debug > Start Debugging để bắt đầu quá trình debugging sẽ xuất hiện hộp thoại sau:
- Nhấp OK để VS chỉnh sửa file Web.config. (Lưu ý nếu chúng ta sử dụng trình duyệt IE thì sẽ xuất hiện thêm hộp thoại yêu cầu cho phép Script Debugging thì thực hiện theo hướng dẫn, trở lại VS và nhấp nút Yes).
- Trang sẽ hiển thị bình thường. Nhập 5 vào textbox thứ nhất và 7 vào textbox thứ hai, chọn phép toán + và nhấn nút Calculate thì, thay vì hiển thị kết quả, bạn sẽ được chuyển tới môi trường VS.
- Dòng mã được thiết lập breakpoint bây giờ sẽ trở thành màu vàng và có một dấu mũi tên ở lề bên trái. Lúc này chúng ta có thể nhìn lướt qua các biến, các controls,… Có thể xem giá trị của các TextBox bằng cách đưa con trỏ chuột lướt qua thuộc tính Text như hình dưới:
- Lưu ý rằng khi chúng ta lướt con trỏ chuột qua các control thì sẽ hiển thị các tooltip, nhưng khi lướt qua các biến như result hay value1 hay value2 thì sẽ không có tooltip vì lúc này chương trình vẫn chưa thực thi tới nơi mà các biến này được khai báo.Nhấn F10 để thực thi các dòng mã kể từ dòng mã được thiết lập breakpoint. Nhấn F10 và giữ cho tới đoạn code khai báo biến value2 có màu vàng (nghĩa là cho thực thi tới dòng code khai báo biến value2 thì dừng). Bây giờ, nếu ta rê chuột qua biến value1 thì sẽ xuất hiện tooltip value1 5.0.
- Lướt chuột đến thuộc tính SelectedValue của DropDownList sẽ xuất hiện tooltip là giá trị được chọn trong DropDownList (phép +):
- Chọn dòng code gán giá trị vào ResultLabel.Text và nhấp chuột phải chọn Run to Cursor để thực hiện tất cả các dòng code từ dòng breakpoint đến dòng code hiện tại đang chọn. Lướt chuột đến biến Result thì hiển thị tooltip với giá trị 12.0
- Nhấn F5 để VS tìm đoạn code có thiết lập điểm dừng kế tiếp, nhưng chúng ta không thiết lập thêm điểm dừng nào nên toàn bộ code trong sự kiện Click sẽ được thực thi và kết quả sẽ được trả lại trong trình duyệt.
Công cụ hỗ trợ Debugging
Visual Studio hỗ trợ bạn một số lớn các công cụ (các phím tắt, cửa sổ,…) giúp bạn có thể tìm và xử lí lỗi một cách hiệu quả nhất.
Khi bạn dùng kĩ thuật điểm dừng (breakpoint), sẽ có một số các phím tắt được hỗ trợ để giúp bạn khai thác hiệu quả kĩ thuật này (bài thực hành trên chúng ta đã dùng F5 và F10). Dưới đây là một số phím được hỗ trợ:
Các phím trên sẽ có những biểu tượng tương ứng trên thanh công cụ như hình sau:
Các cửa sổ hỗ trợ debugging
VS hỗ trợ nhiều cửa sổ để chúng ta có thể xem các biến và sự thay đổi của chúng trong quá trình thực thi nhờ đó cung cấp chúng ta nhiều thông tin hơn. Để hiển thị các cửa sổ này, chúng ta vào Debug > Windows, chú ý rằng một vài cửa sổ chỉ hiển thị trong quá trình debugging. Danh sách các cửa sổ gồm:
Thực hành với các cửa sổ debugging (VB)
Trong bài thực hành này chúng ta sẽ làm quen với hai cửa sổ quan trọng nhất là Watch, Locals, Call Stack và Immediate.
- Mở file CalculatorDemo.aspx.vb và thiết lập breakpoint tại dòng mã khai báo biến value1. Nhấn F5 để bắt đầu quá trình debugging. Nhập 5 vào textbox đầu tiên, 7 vào textbox thứ hai, chọn phép + và nhấn nút Calculate để trở lại cửa sổ VS.
- Rê con trỏ chuột qua biến OperatorList sẽ thấy tooltip xuất hiện. Để ý rằng có một dấu + bên trái tooltip cho phép chúng ta mở rộng để hiển thị thêm thông tin về biến:
- Nhấp chuột phải vào biến value1 trong lệnh If kiểm tra chiều dài chuỗi trong textbox và chọn Add Watch. Bây giờ chúng ta có thể xem thông tin về biến value1 trong cửa sổ Watch giống như trong tooltip. Cuộn cửa sổ đến thuộc tính Text của sẽ thấy giá trị 5:
- Nhấp đôi chuột vào “5” và thay bằng “12”, nhấn Enter.
- Mở cửa sổ Locals bằng cách vào Debug > Windows > Locals:
- Để ý giá trị của value1 trên Locals lúc này là 0.0. Nhấn F10 để thực thi đoạn mã thiết lập breakpoint (tức là thực hiện việc lấy giá trị từ textbox1, đổi sang Double và gán cho value1), lúc này giá trị value1 là 12.0 và có màu đỏ (giá trị chúng ta nhập ở trên):
- Lưu ý rằng việc thay đổi giá trị value1 chỉ diễn ra trên server, không ảnh hưởng đến trình duyệt, nên giá trị trên trình duyệt lúc này vẫn là 5.
- Nhấn F10 thực hiện lệnh gán giá trị cho value2, lúc này value2 sẽ chuyển sang đỏ trong cửa sổ Locals và value1 sẽ trở lại màu đen:
- Nhấn F10 thực hiện các dòng lệnh cho tới lệnh Case gọi phương thức Add (tức là khi dòng mã này có màu vàng). Tới đây, nếu chúng ta tiếp tục nhấn F10 thì VS sẽ thực thi phương thức Add và gán giá trị vào biến result, sau đó nhảy đến lệnh gán giá trị biến result đến thuộc tính Text của Thay vì nhấn F10 để xem kết quả thì chúng ta có thể xem chi tiết code bên trong phương thức Add bằng cách chuyển đến phương thức này với phím F11. Bên trong Add chúng ta có thể rê chuột để xem giá trị của các tham số trong Add:
- Mở cửa sổ Call Stack bằng cách vào Debug > Windows > Call Stack và chúng ta thấy phương thức Add được gọi bởi bộ xử lí sự kiện CalculateButton_Click:
- Nhấp đôi chuột vào dòng thứ hai trong cửa sổ Call Stack, sẽ nhảy đến file CalculatorDemo.aspx.vb và dòng mã gọi phương thức Add sẽ có màu xanh. Lưu ý ở đây không thực hiện bất cứ dòng mã nào:
- Nhấp lại dòng đầu tiên trong Call Stack sẽ trở lại phương thức Add.
- Bấm Shift + F11 để thoát khỏi phương thức Add và trở lại đoạn mã đã gọi nó, lúc này các dòng mã trong cửa sổ Call Stack về phương thức Add đã biến mất:
- Lúc này biến result vẫn chưa có giá trị vì đoạn code này vẫn chưa thực thi.
- Mở cửa sổ Immediate bằng cách vào Debug > Windows > Immediate để kiểm tra nhanh vài lệnh. Gõ lệnh sau trong cửa sổ và Enter:
? New Calculator().Multiply(4, 12)
Trong cửa sổ Immediate sẽ hiển thị kết quả:
- Nhấn F10 để thực thi code hiện tại. Lúc này, mũi tên màu vàng sẽ nhảy đến cuối khối lệnh Select..Case
- Nhấp và rê chuột đưa mũi tên màu vàng trở lại lệnh myCalculator.Add:
- Việc này để yêu cầu VS thực thi lại đoạn mã nếu nhấn F10 hoặc vào phương thức Add nếu nhấn F11.
- Nhấn F5 hiển thị kết quả trên trình duyệt:
Debugging với Page Inspector
Là công cụ debugging mới được tích hợp trong VS 2012, mang lại trải nghiệm hợp nhất giữa trình duyệt, ASP.NET run time và source code. Công cụ này tương tự FireBug trong FireFox hay IE, Chrome Developer, nhưng có điều đặc biệt là nó có thể tạo mối quan hệ hai chiều giữa mã client (HTML, CSS, Script) trên trình duyệt và mã ASP.NET. Nó cho phép chúng ta tạo trên IDE, chỉnh sửa và xem trước kết quả.
Điều kiện dùng Page Inspector:
- Cài phiên bản IE 9 trở lên.
- Dùng .NET 4.0 trở lên.
- Hoạt động trong chế độ Debug và thêm thông tin vào Web.config cho phép Page Inspector hoạt động.
Thực hành dùng Page Inspector (VB)
- Chọn trang CalculatorDemo.aspx. Trên thanh công cụ tại danh sách Target Browser (nơi có tên trình duyệt như Google Chrome hay Internet Explorer), nhấp mũi tên hướng xuống bên phải, chọn Page Inspector:
- Nhấn F5 để bắt đầu debugging, sau vài giây Page Inspector sẽ xuất hiện trong VS như sau:
- Đóng hết tất cả các cửa sổ (bao gồm cả Solution Explorer) chỉ để lại cửa sổ Page Inspector. Hai nút gốc trái trên Page Inspector là Browser để hiển thị trang như trong trình duyệt, Problems cho biết thông tin lỗi trang với số lỗi bên cạnh (trong trường hợp này là 0 vì không có lỗi):
- Phía dưới chúng ta có hai màn hình chứa các nút. Bên trái gồm nút HTML để hiển thị mã HTML, nút Inspect để dò tìm các phần tử trong trang và nút Files hiển thị file trên server:
- Nhấn nút Inspector và rê con trỏ chuột đến phần tử bất kì trong trang, ví dụ textbox1 thì mã của textbox này sẽ phát sinh tương ứng bên dưới:
- Trong cửa sổ code bên phải, tìm đến DropDownList và trong ListItem thử thay đổi dấu + bằng một đoạn text bất kì thì sẽ xuất hiện cảnh báo:
- Bấm Ctrl + Alt + Enter để reload trang lại. Lúc này, dòng text vừa gõ sẽ thay thế dấu + trong DropDownList:
- Cửa sổ các nút bên phải như Styles, Trace Styles, Layout và Attribute cho phép chúng ta theo dõi thông tin về CSS, các thuộc tính của các phần tử trong trang.
Debugging với tracing (tìm vết)
Tracing là khả năng tìm vết để theo dõi các thành phần trong trang aspx hay toàn bộ site. Tracing được tích hợp sẵn trong ASP.NET Framework.
Tracing một trang aspx
Để tracing một trang nào đó, ta cần mở trang trong chế độ Source, tìm đến <Page> và thêm thuộc tính Trace:
<%@ Page ........ Trace="true" %>
Khi chúng ta cho phép chức năng trace trong một trang bất kì thì khi thực thi trang trên trình duyệt sẽ xuất hiện các thông tin kèm theo, ví dụ trang CalculatorDemo.aspx:
Tracing toàn bộ site (áp dụng cho toàn bộ trang trong site)
Thêm phần tử <trace /> vào trong <system.web> trong file Web.config. Một số thuộc tính quan trọng kèm theo phần tử trace:
Thực hành với tracing (VB)
- Mở Web.config và thêm phần tử <trace /> với các thuộc tính kèm theo vào trong phần tử <system.web> như sau:
- Mở trang aspx và Ctrl + F5:
- Thông tin về trang sẽ hiển thị và chúng ta có thể tìm hiểu các thông tin cần thiết.
- Trên thanh địa chỉ của trình duyệt, gõ thông tin sau để yêu cầu trình xử lí axd:
- Kết quả sẽ cho thông tin sau trên trình duyệt:
Thêm thông tin đến trace
Chúng ta có thể thêm thông tin cá nhân đến trace để tiện theo dõi các thành phần trong ứng dụng. Để làm điều này, chúng ta dùng lớp Trace với hai phương thức cơ bản là Write và Warn.
Thực hành thêm thông tin vào trace (VB)
- Mở file CalculatorDemo.aspx.vb, trong trình xử lí sự kiện Click, chúng ta thêm đoạn code Trace.Write ở trên câu lệnh Select Case như sau:
- Thêm câu lệnh Trace.Warn vào lệnh Else:
- Lưu và trở lại trang CalculatorDemo.aspx, Ctrl + F5. Nhập thông tin vào textbox1 và textbox2 ta sẽ thấy xuât hiện dòng thông tin trong lệnh Trace.Write ở giữa Begin Raise PostBackEvent và End Raise PostBackEvent:
- Xoá các thông tin trong một hoặc cả hai textbox và nhấn nút Calculate sẽ xuất hiện cảnh báo trong lệnh Warn:
- Trở lại VS và Stop Debugging.
Cảnh báo: Vì tính bảo mật nên bạn không nên lạm dụng trace mà luôn luôn thiết lập thuộc tính enabled đến false hoặc localOnly đến true.
Ý kiến bài viết

markdown:
**Nhập môn lập trình**
Một trang web (hay website) được tạo ra gồm ba yếu tố cơ bản là giao diện, nội dung và tính tương tác. Tính tương tác của trang web có được nhờ lập trình.
Lập trình với
**ASP.NET** bao gồm hai ngôn ngữ phổ biến là **Visual Basic (VB)** và **C#**. Mỗi ngôn ngữ đòi hỏi nhiều thời gian và công sức để khám phá. Trong chương này chỉ tìm hiểu những nét cơ bản nhất trong **Visual Basic (VB) và C#**.
**Sơ lược về quá trình biên dịch của ASP.NET run time**
Khi
**ASP.NET** **run time** yêu cầu một trang aspx nào đó, nếu trang chứa code ( **VB** hay **C#**), thì nó sẽ biên dịch (compile) các code này sang ngôn ngữ **MSIL (Microsoft Intermediate Language)** để . **NET Framework** có thể hiểu và thực thi. Kết quả của quá trình biên dịch sẽ là một loạt các file có phần mở rộng là **DLL** và được lưu trong một thư mục tạm nào đó trong máy tính. Quá trình biên dịch chỉ diễn ra khi trang aspx được yêu cầu lần đầu, những lần yêu cầu sau với trang này, **ASP.NET run time** sẽ dùng lại các file **DLL** được tạo ra trước đó.
**Kiểu dữ liệu **
Các ngôn ngữ lập trình thường cung cấp một danh sách các kiểu dữ liệu (data type) khác nhau dùng để biểu diễn các kiểu thông tin khác nhau như số (numbers), thời gian (date, time), văn bản (text), v.v.
**Microsoft .NET** hỗ trợ rất nhiều ngôn ngữ lập trình như **C#**, **VB**, v.v. và các ngôn ngữ này có thể giao tiếp được với nhau. Ví dụ khi biên dịch file **C#** thành các file DLL thì các file **DLL** này có thể được dùng trong ứng dụng **VB**. Vì các ngôn ngữ lập trình có thể giao tiếp qua lại với nhau nên cần có một hệ thống các kiểu chung để các ngôn ngữ có thể hiểu được nhau, hệ thống này được gọi là **CTS (Common Type System)**. Mỗi ngôn ngữ lập trình sẽ định nghĩa cho mình các kiểu dữ liệu và chúng tham chiếu đến kiểu dữ liệu chung trong **CTS**. Ví dụ, trong **VB** có kiểu integer, **C#** có kiểu int, và cả hai kiểu này cùng tham chiếu đến kiểu System.Int32 trong **CTS**.
Bảng dưới đây là danh sách các kiểu trong
**CTS** và tương ứng với chúng trong **C#** hay **VB**:
|
|CTS |
|C# |
|VB |
|Mô tả
|System.Byte||byte||Byte||Lưu trữ các số nguyên dương từ 0 -255. Mặc định là 0.|
|System.Int16||short||Short||Lưu trữ các số nguyên có dấu từ -32,768 đến +32,767. Mặc định là 0.|
|System.Int32||int||Integer||Lưu trữ các số nguyên có dấu từ –2,147,483,648 đến +2,147,483,647. Mặc định là 0.|
|System.Int64||long||Long||Lưu trữ các số nguyên có dấu từ
|
–9,223,372,036,854,775,808 đến +9,223,372,036,854,775,807. Mặc định là 0.
|System.Single||float||Single||Lưu trữ các số thực có dấu từ
|
–3.4028235E+38 đến
+ 3.4028235E+38. Mặc định là 0.0.
|System.Double||double||Double||Lưu trữ các số thực rất lớn. Mặc định là 0.0.|
|System.Decimal||decimal||Decimal||Lưu trữ các số thực rất lớn. Mặc định là 0. Thường dùng trong biểu diễn tiền tệ.|
|System.Boolean||bool||Boolean||Lưu trữ hai giá trị là True hay False (VB)(true, false trong C#). Mặc định là False (hay false).|
|System.DateTime||n/a||Date||VB hỗ trợ để lưu trữ date và time. C# không hỗ trợ. Mặc định là 1/1/0001: 12:00 am.|
|System.Char||char||Char||Lưu trữ một kí tự. Mặc định là Nothing (VB) hay null (C#).|
|System.String||string||String||Lưu trữ chuỗi có thể lên đến 2 tỉ kí tự. Mặc định là Nothing (VB) hay null (C#).|
|System.SByte||sbyte||SByte||Lưu trữ các số nguyên có dấu từ -128 đến +127. Mặc định là 0.|
|System.UInt16||ushort||UShort||Lưu trữ các số nguyên không dấu từ 0 đến 65,535. Mặc định là 0.|
|System.UInt32||uint||UInteger||Lưu trữ các số nguyên không dấu từ 0 đến 4,294,967,295. Mặc định là 0.|
|System.UInt64||ulong||ULong||Lưu trữ các số nguyên không dấu từ 0 đến 18,446,744,073,709,551,615. Mặc định là 0.|
|System.Object||object||Object||Là cha của tất cả các kiểu dữ liệu. Mỗi kiểu dữ liệu là một object. Mặc định là Nothing (VB) hay null (C#).|
**Biến**
Để làm việc với các dữ liệu, chúng ta cần lưu trữ nó trong một biến. Cú pháp khai báo một biến trong
**VB** là:
Dim tên_biến As Kiểu_Dữ_Liệu
Trong
**C#**
Kiểu_Dữ_Liệu tên_biến;
Khai báo biến bắt đầu bằng từ khoá
**Dim**. **tên_biến** là tên của biến cần khai báo gồm các kí tự, số, dấu _, và không được bắt đầu bằng số. Từ khoá **As** dùng để chỉ kiểu dữ liệu cho biến. **Kiểu_Dữ_Liệu** là một trong các kiểu dữ liệu **(VB)** ở bảng trên.
Với
**C#**, thứ tự **tên_biến** và **Kiểu_Dữ_Liệu** ngược lại.
Ví dụ khai báo một biến kiểu
**Integer,** tên biến là x và một biến kiểu **String,** tên biến là s như sau: **Mã VB**
Dim x As Integer Dim s As String
**Mã C#**
int x; string s;
Sau khi khai báo biến, chúng ta có thể gán giá trị cho chúng, ví dụ với hai biến trên và để ý đối với biến s kiểu
**String** thì giá trị của nó là một chuỗi kí tự được đặt trong cặp dấu “:
x = 5 s = "Hello "
Chúng ta cũng có thể kết hợp khai báo và gán giá trị cho biến như ví dụ:
**Mã VB**
Dim x As Integer = 5 Dim s As String = "Hello"
**Mã C#**
int x = 5; string s = "Hello ";
**Một số chú ý khi đặt tên biến:**
- Không bắt đầu bằng số.
- Không trùng với các từ khoá (keywords), là các từ vựng có sẵn trong ngôn ngữ.
- Đặt theo mục đích, ví dụ firstName, age.
- Tuân theo chuẩn
**camel case**, tức là nếu tên biến gồm nhiều từ như firstName (gồm first và Name) thì từ đầu tiên viết thường tất cả các kí tự, các từ kế tiếp sẽ viết hoa kí tự đầu tiên, như first **N**ame.
**Chuyển và ép kiểu**
Chuyển kiểu (converting data types) thường dùng phương thức
**ToString()** để chuyển một kiểu bất kì về kiểu **String** hay có thể dùng các phương thức trong lớp **Convert**. Xem các ví dụ: **Mã VB**
Label1.Text = System.DateTime.Now.ToString() Dim myBoolean1 As Boolean = Convert.ToBoolean("True")
**Mã C#**
Label1.Text = System.DateTime.Now.ToString(); bool myBoolean1 = Convert.ToBoolean("True");
Bên cạnh phương thức
**ToBoolean** chuyển một kiểu đến kiểu **Boolean** thì trong **Convert** còn có các phương thức **ToInt32** (chuyển đến kiểu số nguyên), phương thức **ToDateTime** (chuyển đến thời gian), phương thức **ToString** (chuyển đến chuỗi) (chú ý đây là phương thức của lớp **Convert**, phương thức **ToString** ở trên là của một object bất kì).
Kĩ thuật chuyển kiểu (converting) chuyển giá trị của một kiểu dữ liệu sang giá trị mới. Còn một phương pháp khác để chuyển kiểu là ép kiểu (casting). Ép kiểu thật sự biến một kiểu thành một kiểu khác. Trong VB có hai cách dùng để ép kiểu là dùng
**CType** và **DirectCast (**hay ** TryCast)**. **CType** ép kiểu hai đối tượng giống nhau, **DirectCast** ép hai kiểu tương thích nhau. Xem ví dụ: **Mã VB**
Dim o1 As Object = 1 Dim i1 As Integer = DirectCast(o1, Integer) Dim i2 As Integer = CType(o1, Integer) Dim o2 As Double = 1 Dim i3 As Integer = DirectCast(o2, Integer) Dim i4 As Integer = CType(o2, Integer)
**i1** và **i2** thành công vì **o1** là một **Integer**, **i3** không thành công vì hai kiểu **Integer** và **Double** không tương thích nhau, **i4** thành công vì **o2** trông như một số nguyên.
Trong C# có hai cách ép kiểu:
- Cách thứ nhất là đặt biểu thức gồm kiểu (kiểu cần chuyển đến) được đặt trong cặp ngoặc đơn trước đối tượng (hay biến) cần ép kiểu. Cách này tương đương dùng
**CType**trong VB.
- Cách thứ hai là dùng từ khoá
**as**tương đương dùng **TryCast**trong VB. **Mã C#**
object o1 = 1; int i1 = (int)o1; // dùng cách thứ nhất double o2 = 1; int i2 = o2 as int;// dùng cách thứ hai
**Mảng (array), collection, generic**
**Mảng (array)** **Mảng** là một danh sách chứa các phần tử cùng kiểu như các số nguyên, chuỗi,…Mỗi phần tử trong mảng được xác định tại một vị trí được gán chỉ số (index). Phần tử ở vị trí đầu tiên sẽ có chỉ số là 0, phần tử cuối cùng trong mảng có n phần tử có chỉ số là n – 1. Khai báo, truy cập (gán giá trị, hiển thị ) các phần tử mảng trong VB dùng dấu ngoặc tròn, dùng ngoặc vuông trong **C#**. **Cú pháp VB**
Dim tên_mảng(chỉ số cao nhất trong mảng) As kiểu_dữ_liệu
**Cú pháp C#**
kiểu_dữ_liệu[] tên_mảng = new kiểu_dữ_liệu[kích cỡ hay số phần tử trong mảng];
Khác với một số ngôn ngữ họ C như C# hay Java, khai báo mảng trong VB không dùng kích cỡ mảng mà là dùng chỉ số cao nhất có thể có trong mảng. Ví dụ khai báo mảng trong VB chứa 2 số nguyên tên
**arrInt** như sau:
Dim arrInt(1) As Integer
Mảng
**arrInt** chứa hai số nguyên nên phần tử đầu tiên có chỉ số 0, phần tử thứ hai có chỉ số 1 và đây là chỉ số cao nhất nên trong khao báo trên dùng **arrInt(1).**
Trong khi đó khai báo trong C# như sau:
int[] arrInt = new int [2];
Gán giá trị cho các phần tử trong mảng ta dùng cú pháp VB:
tên_mảng (chỉ số của phần tử) = giá trị
Cú pháp C#:
tên_mảng [chỉ số của phần tử] = giá trị;
Ví dụ gán các giá trị số nguyên cho hai phần tử trong mảng
**arrInt** như sau: **Mã VB:**
arrInt (0) = 7 ' Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt (1) = 19 ' Gán 19 cho phần tử thứ hai arrInt (2) = 5 ' lỗi vì mảng chỉ chứa tối đa 2 phần tử
**Mã C#:**
arrInt [0] = 7; // Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt [1] = 19; // Gán 19 cho phần tử thứ hai arrInt [2] = 5; // lỗi vì mảng chỉ chứa tối đa 2 phần tử
*
**Chú ý**: theo sau mỗi dòng lệnh là dấu ‘ và dòng văn bản, đó là các chú thích trong VB; chú thích trong C# là //.
Để truy cập phần tử trong mảng ta dùng cú pháp VB:
tên_mảng (chỉ số phần tử)
Cú pháp C#:
tên_mảng [chỉ số phần tử];
Khi khai báo mảng chúng ta thường gán cho mảng một kích cỡ nào đó mặc định, nhưng trong thực tế có thể giảm hoặc tăng kích thước ban đầu. Để khai báo lại kích thước mảng và làm mới lại toàn bộ các phần tử trong mảng ta dùng cú pháp trong VB:
ReDim tên_mảng (chỉ số cao nhất cập nhật)
Trong trường hợp chúng ta muốn tăng kích thước mảng đồng thời muốn giữ lại các giá trị đã gán cho các phần tử trong mảng trước đó, chúng ta dùng cú pháp như trên nhưng có thêm từ khoá
**Preserve**, cú pháp:
ReDim Preserve tên_mảng (chỉ số cao nhất cập nhật)
Ví dụ:
Dim arrInt(1) As Integer arrInt (0) = 7 ' Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt (1) = 19 ' Gán 19 cho phần tử thứ hai arrInt (2) = 5 ' lỗi ReDim Preserve arrInt(2) arrInt (2) = 5 ReDim Preserve arrInt(3) ' các phần tử trong arrInt trở thành Nothing
Trong C# không có từ khoá để làm mới lại kích cỡ mảng nhưng chúng ta có thể dùng phương thức tĩnh
**Resize** của lớp **Array**. Ví dụ với mảng **arrInt** như sau:
int[] arrInt = new int[2]; arrInt [0] = 7; //Gán giá trị 7 cho phần tử thứ nhất trong mảng arrInt [1] = 19; //Gán 19 cho phần tử thứ hai arrInt (2) = 5; // lỗi Array.Resize (ref arrInt, 3); arrInt [2] = 5;
**Collection**
Cấu trúc mảng thiếu một vài tính năng hữu ích như thêm, xoá, sửa các phần tử của mảng. Điều này được hỗ trợ bởi các
**collection**. Với **collection,** nếu chúng ta muốn truy cập các phần tử, thay vì thông qua chỉ số như trong mảng, chúng ta sẽ dùng các phương thức như **Add**, **Remove** hay **Clear**. Có thể lặp qua các phần tử trong **collection** như lặp qua các phần tử trong mảng. Hai **collection** phổ biến nhất, được giới thiệu từ **.NET Framework** **1.0**, là **ArrayList** và **HashTable** (bảng băm).
Một tiện ích khác của collection, như
**ArrayList**, là việc không cần cập nhật lại kích cỡ như mảng, kích cỡ **collection** sẽ cập nhật tự động sau mỗi lần thêm, xoá phần tử bất kì.
Ví dụ tạo một
**ArrayList** và gán các giá trị số nguyên vào **ArrayList** này: **Mã VB**
Dim arrLst As New ArrayList ()' có từ khoá New, không có kiểu dữ 'liệu và chỉ số arrLst.Add (7) ' thêm phần tử thứ nhất arrLst.Add (19) ' thêm phần tử thứ hai
**Mã C#**
ArrayList arrLst = new ArrayList (); //có từ khoá New, không có // kiểu dữ liệu và chỉ số arrLst.Add (7); // thêm phần tử thứ nhất arrLst.Add (19); //thêm phần tử thứ hai
**Generic**
Trở ngại lớn nhất của
**collection** là nó không quan tâm đến kiểu dữ liệu, nghĩa là ta có thể thêm bất kì đối tượng nào vào **collection. .NET Framework 2.0** giới thiệu một khái niệm mới gọi là **generic**, giúp khắc phục điểm yếu và kế thừa những điểm mạnh của **collection**. **Generic** là một template chứa các đoạn mã có thể được dùng trong những hoàn cảnh khác nhau với những kiểu dữ liệu khác nhau. Ví dụ tạo một danh sách theo kiểu **generic** chứa các số nguyên, giống **ArrayList** nhưng có ràng buộc kiểu: **Mã VB**
Dim arrGn As New List(Of Integer) arrGn.Add(7) arrGn.Add(19)
**Mã C#**
List<int> arrGn = new List<int>(); arrGn.Add(7); arrGn.Add(19);
Để thêm phần tử vào
**collection** hay **generic** chúng ta có thể dùng phương thức **Add**, ngoài ra, . **NET** còn hỗ trợ một tính năng gọi là **collection initializer**. Với tính năng này, chúng ta có thể thêm các phần tử vào **collection** hay **generic** chỉ bằng một dòng lệnh (thay vì nhiều lệnh **Add**).
Ví dụ thêm các phần tử vào danh sách generic
**arrGn**: **Mã VB:**
Dim arrGn As New List(Of Integer) From {7, 19}
**Mã C#:**
List<int> arrGn = new List<int>() {7, 19};
**Toán tử (operator)** **Toán tử gán (assigment operator)**
Dùng để gán một giá trị đến một biến. Giá trị này có thể là hằng (như 6 hay “hello”), giá trị của biến khác, kết quả của một biểu thức hay hàm.
Kí hiệu:
**=**
Ví dụ: gán giá trị 6 cho biến x trong VB
Dim x As Integer = 6
**Mã C#**
int x = 6;
**Toán tử số học (arithmetic operator)**
Cho phép thực hiện các thao tác tính toán. Gồm:
|
|VB |
|C# |
|Chức năng
|+||+||Cộng hai giá trị|
|–||–||Trừ hai giá trị|
|*||*||Nhân hai giá trị|
|/||/||Chia hai giá trị|
|\||n/a||Chia hai giá trị và kết quả luôn được làm tròn|
|^||n/a||Luỹ thừa|
|Mod||%||Lấy dư từ phép chia|
Ví dụ trong VB
Dim firstNumber As Integer = 100 Dim secondNumber As Single = 23.5 Dim result As Double = 0 result = firstNumber + secondNumber ' Kết quả 123.5 result = firstNumber - secondNumber ' Kết quả 76.5 result = firstNumber * secondNumber ' Kết quả 2350 result = firstNumber / secondNumber ' Kết quả 4.25531914893617 result = firstNumber \ secondNumber ' Kết quả 4 Dim result As Double result = 2 ^ 3 ' Kết quả 8 (2 * 2 * 2) result = 3 ^ 2 ' Kết quả 9 (3 * 3) Dim firstNumber As Integer = 17 Dim secondNumber As Integer = 3 Dim result As Integer = firstNumber Mod secondNumber ' Kết quả 2
*** Chú ý:** C# không hỗ trợ toán tử **\**, tuy nhiên, nếu chúng ta chia hai số nguyên, ví dụ lấy 7 chia 3, thì kết quả sẽ là một số nguyên, ví dụ 7 chia 3 là 3. Điều này chúng ta cần chú ý vì sẽ không cho kết quả như mong đợi. C# cũng không hỗ trợ toán tử ^ mà sẽ dùng phương thức **Pow** của lớp **Math** thay thế.
Độ ưu tiên của các toán tử trong biểu thức theo thứ tự giảm dần từ trên xuống như sau:
|
|VB |
|C#
|^||*, /, %|
|*, /||+, –|
|\|
|Mod|
|+, –|
|& (cộng chuỗi)|
VB hay C# cho phép kết hợp toán tử số học và toán tử gán. Xem bảng dưới đây:
|
|Toán tử |
|Ví dụ |
|Ý nghĩa
|+=||x += 3||x = x + 3|
|-=||x -= 3||x = x – 3|
|*=||x *= 3||x = x * 3|
|/=||x /= 3||x = x / 3|
|\= (VB)||x \= 3||x = x \ 3|
|^= (VB)||x ^= 3||x = x ^ 3|
|Mod=(%=)||x Mod= 3 (x %= 3)||x = x Mod 3|**Toán tử so sánh (comparison operator)**
Cho phép so sánh hai giá trị, thường dùng trong các biểu thức điều kiện. Kết quả trả về là True hay False. Một số toán tử so sánh phổ biến:
|
|VB |
|C# |
|Chức năng
|=||==||Kiểm tra hai giá trị có bằng nhau không|
|<>||!=||Kiểm tra hai giá trị khác nhau|
|<||<||Kiểm tra giá trị đầu có bé hơn giá trị sau không|
|>||>||Kiểm tra giá trị đầu có lớn hơn giá trị sau không|
|<=||<=||Kiểm tra giá trị đầu có bé hơn hoặc bằng giá trị sau không|
|>=||>=||Kiểm tra giá trị đầu có lớn hơn hoặc bằng giá trị sau không|
|Is||is||
|Trong VB: so sánh hai object với nhau; trong C#: kiểm tra một biến có phải là một kiểu dữ liệu nào đó. **Toán tử cộng chuỗi (concatention operator)**
Để kết hợp hai chuỗi (kiểu String) trong VB chúng ta có thể dùng toán tử &, trong C# dùng +. Có thể kết hợp với toán tử gán là += hay &=. Tuy nhiên, để tránh xảy ra một số lỗi không mong đợi, khi kết hợp hai chuỗi chúng ta dùng &.
Ví dụ: khai báo các biến sau:
**Mã VB**
Dim firstString As String = "Hello" Dim secondString As String = "World" Dim result As String
**Mã C#**
string firstString = "Hello"; string secondString = "World"; string result;
Kết hợp hai chuỗi trong biến firstString và secondString và lưu kết quả trong biến result có thể viết như sau:
**Mã VB**
result = firstString & secondString
hoặc
result = firstString result = result & secondString
hoặc
result = firstString result &= secondString
**Mã C#**
result = firstString + secondString;
hoặc
result = firstString; result = result + secondString;
hoặc
result = firstString; result += secondString;
Trong VB thỉnh thoảng cũng dùng toán tử + để nối hai chuỗi, tuy nhiên, không nên dùng toán tử này (trong VB) vì có thể xảy ra kết quả không như mong đợi như ví dụ sau:
Dim firstNumber As String = "4" Dim secondNumber As Integer = 5 Dim result As String = firstNumber + secondNumber
Kết quả trong result thay vì là chuỗi “45” thì kết quả là 9
**Toán tử luận lý (logical operator)**
Trả về giá trị True hay False từ việc kết hợp nhiều biểu thức. Một số toán tử
|
|VB |
|C# |
|Chức năng
|And||&||Trả về True nếu tất cả các biểu thức đều trả về True|
|Or|||||Trả về True nếu ít nhất một biểu thức trả về True|
|Not||!||Trả về True nếu biểu thức là False và ngược lại|
|AndAlso||&&||Tương tự And nhưng sẽ không kiểm tra các biểu thức còn lại nếu biểu thức đầu tiên quyết định kết quả trả về.|
|OrElse||
||| |Tương tự Or nhưng sẽ không kiểm tra các biểu thức còn lại nếu biểu thức đầu tiên quyết định kết quả trả về.|
Ví dụ:
**Mã VB:**
Dim num1 As Integer = 3 Dim num2 As Integer = 7 num1 = 3 And num2 = 7 ' True num1 = 2 And num2 = 7 ' False num1 = 3 Or num2 = 11 ' True Not num1 = 5 ' True num1 = 2 AndAlso num2 = 7 ' trả về False vì num1 khác 2 và không ' cần kiểm tra biểu thức num2 = 7
**Mã C#:**
int num1 = 3; int num2 = 7; num1 == 3 & num2 == 7 // true num1 == 2 & num2 == 7 // false num1 == 3 | num2 == 11 // true !(num1 == 5) // true num1 == 2 && num2 == 7 //trả về false vì num1 khác 2 và không //cần kiểm tra biểu thức num2 = 7
** ** **Các lệnh điều kiện (conditional statement) **
Khi viết code, chúng ta hay gặp những tình huống phải đưa ra những hành động khác nhau trong những điều kiện khác nhau. Để làm điều này, chúng ta sử dụng các lệnh điều kiện (conditional statements).
Lệnh điều kiện trong VB gồm lệnh
**If** và **Select Case;** trong C# là **if** và **switch.** Lệnh **If** có các phiên bản sau: **Lệnh If** **VB**
If điều kiện Then khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay True) End If
**C#**
if (điều kiện){ khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) }
Ví dụ:
**Mã VB:**
If tuoi < 18 Then thongbao = "Ban chua du tuoi" End If
**Mã C#:**
if tuoi < 18){ thongbao = "Ban chua du tuoi"; }
**Lệnh If…Else** **VB**
If điều kiện Then khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) Else khốí lệnh sẽ thực thi nếu điều kiện là sai (hay false) End If
**C#**
if (điều kiện){ khốí lệnh sẽ thực thi nếu điều kiện là đúng (hay true) } else { khốí lệnh sẽ thực thi nếu điều kiện là sai (hay false) }
Ví dụ:
**Mã VB**
If tuoi < 18 Then thongbao = "Ban chua du tuoi" Else thongbao = "Chao mung ban den voi website chung toi!" End If
**Mã C#**
if (tuoi < 18){ thongbao = "Ban chua du tuoi"; } else { thongbao = "Chao mung ban den voi website chung toi!"; }
**Lệnh If…ElseIf…Else** **VB**
If điều kiện 1 Then khốí lệnh sẽ thực thi nếu điều kiện 1 là đúng (hay true) ElseIf điều kiện 2 Then khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là đúng (hay true) Else khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là sai (hay false) End If
**C#**
if (điều kiện 1){ khốí lệnh sẽ thực thi nếu điều kiện 1 là đúng (hay true) } else if (điều kiện 2){ khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là đúng (hay true) } else { khốí lệnh sẽ thực thi nếu điều kiện 1 là sai (hay false) và điều kiện 2 là sai (hay false) }
Ví dụ:
**Mã VB**
If time < 10 Then greeting = "Good morning" ElseIf time < 20 greeting = "Good day" Else greeting = "Good evening" End If
**Mã C#**
if (time < 10){ greeting = "Good morning"; } else if (time < 20){ greeting = "Good day"; } else{ greeting = "Good evening"; }
Cũng là lệnh điều kiện giống If dùng để đưa ra những hành động khác nhau trong những điều kiện khác nhau, chúng ta có thể dùng Select Case trong VB hay switch trong C#.
**Cú pháp Select Case:**
Select Case bieu_thuc Case n khối lệnh Case m: khối lệnh Case Else khối lệnh mặc định End Select
Ví dụ:
Dim today As DateTime = DateTime.Now Dim discountPercentage As Double = 0 Select Case today.DayOfWeek Case DayOfWeek.Monday discountPercentage = 40 Case DayOfWeek.Tuesday discountPercentage = 30 Case DayOfWeek.Wednesday discountPercentage = 20 Case DayOfWeek.Thursday discountPercentage = 10 Case Else discountPercentage = 0 End Select
**Cú pháp switch:**
switch (bieu_thuc){ case n: khối lệnh break; case m: khối lệnh break; default: khối lệnh mặc định break; }
Ví dụ:
DateTime today = DateTime.Now; double discountPercentage = 0; switch (today.DayOfWeek) { case DayOfWeek.Monday: discountPercentage = 40; break; case DayOfWeek.Tuesday: discountPercentage = 30; break; case DayOfWeek.Wednesday: discountPercentage = 20; break; case DayOfWeek.Thursday: discountPercentage = 10; break; default: discountPercentage = 0; break; }
**Lệnh lặp (loop statement)**
Trong lập trình, có những lệnh hay khối lệnh được lặp lại nhiều lần. Thay vì viết các lệnh hay khối lệnh này nhiều lần, chúng ta có thể dùng các lệnh lặp.
Trong VB có các lệnh lặp là For, For/In, While và Do/While.
**Lệnh For**
Dùng để lặp theo một số lần xác định cho trước, ví dụ thực hiện lệnh xuất dòng chữ Hello 5 lần.
Cú pháp lệnh For trong VB:
For Biến_đếm [ As Kiểu_dữ_liệu ] = Bắt_đầu To Kết_thúc [Step Bước_lặp] ' Đoạn mã được lặp Next [Biến_đếm ]
Những thành phần chứa trong [ ] là tuỳ chọn (có hoặc không).
Cú pháp lệnh For trong C#:
for (điều kiện bắt đầu lặp; điều kiện kết thúc lặp; bước lặp) { // Đoạn mã được lặp }
Ví dụ hiển thị các số nguyên từ 1 đến 10 trên 10 hàng trong một Label control:
**Mã VB:**
For loopCount As Integer = 1 To 10 Label1.Text &= loopCount.ToString() & "<br />" Next
**Mã C#:**
for (int loopCount = 1; loopCount <= 10; loopCount ++) { Label1.Text += loopCount.ToString() + "<br />"; }
Hiển thị các số chẵn trong dãy số nguyên từ 0 đến 10
**Mã VB:**
For loopCount As Integer = 0 To 10 Step 2 Label1.Text &= loopCount.ToString() & "<br />" Next
**Mã C#:**
for (int loopCount = 0; loopCount <= 10; loopCount = loopCount + 2) { Label1.Text += loopCount.ToString() + "<br />"; }
Hiển thị các phần tử trong mảng:
**Mã VB:**
Dim arrInt(2) As Integer arrInt (0) = 7 arrInt (1) = 19 arrInt (2) = 5 For loopCount As Integer = 0 To arrInt.Length - 1 Label1.Text &= arrInt(loopCount).ToString() & "<br />" Next
**Mã C#:**
int arrInt[] = new int[3]; arrInt [0] = 7; arrInt [1] = 19; arrInt [2] = 5; for (int loopCount = 0; loopCount < arrInt.Length; loopCount ++) { Label1.Text += arrInt[loopCount].ToString() + "<br />"; }
**Lệnh For Each**
Dùng để lặp qua các phần tử trong
**collection** hay **generic.** Ví dụ: **Mã VB**:
Dim arrGn As New List(Of Integer) From {7, 19} For Each item As Integer In arrGn Label1.Text &= item.ToString() & "<br />" Next
**Mã C#**:
List<int> arrGn = new List<int>() {7, 19}; foreach (int item in arrGn) { Label1.Text += item.ToString() + "<br />"; }
**Lệnh While**
Khác với For, lệnh While sẽ lặp theo một điều kiện nào đó. Chừng nào điều kiện còn đúng thì lệnh lặp sẽ vẫn thực thi.
Cú pháp trong VB:
While dieu_kien Đoạn mã được lặp End While
Cú pháp trong C#:
while (dieu_kien) { Đoạn mã được lặp }
Ví dụ: lệnh lặp sau sẽ còn thực thi chừng nào điều kiện i < 10 còn đúng, biến i sẽ tăng 1 đơn vị sau mỗi lần lặp
**Mã VB:**
Dim i As Integer = 0 While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 End While
**Mã C#:**
int i = 0; while (i < 10) { Label1.Text += "The number is " + i.ToString(); i = i + 1; // hay i++; }
**Lệnh Do While, Do Until**
Trong VB còn có lệnh Do While Do Until giống lệnh While là lặp khi điều kiện là đúng
Cú pháp VB:
Do {While | Until} dieu_kien Đoạn mã được lặp Loop
Ví dụ:
**Mã VB**
Dim i As Integer = 0 Do While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 Loop
**Mã C#**
int i = 0; do { Label1.Text += "The number is " + i.ToString(); i = i + 1; } while (i < 10);
**Lệnh Do..Loop {While | Until} **
Giống lệnh Do While hay Do Until nhưng Do..Loop thực hiện lệnh ít nhất một lần.
Cú pháp VB:
Do Đoạn mã được lặp Loop {While | Until} dieu_kien
Cú pháp C#:
do { Đoạn mã được lặp } while (dieu_kien);
Xét ví dụ sau để phân biệt While và Do..Loop (hay while và do…while):
Đoạn mã sau sẽ không thực thi vì i = 11 >10
**Mã VB**
Dim i As Integer = 11 While i < 10 Label1.Text &= "The number is " & i.ToString() i = i + 1 End While
**Mã C#**
int i = 11; while (i < 10) { Label1.Text += "The number is " + i.ToString(); i = i + 1; }
Đoạn mã sau sẽ thực thi và kết quả là The number is 11
**Mã VB**
Dim i As Integer = 11 Do Label1.Text &= "The number is " & i.ToString() i = i + 1 Loop While i < 10
**Mã C#**
int i = 11; do { Label1.Text += "The number is " + i.ToString(); i = i + 1; } while (i < 10);
**Lệnh thoát vòng lặp**
Có thể thoát khỏi vòng lặp While, Do hay For bằng lệnh Exit Do, Exit Do hay Exit For (break trong C#). Ví dụ: vòng lặp sau sẽ thoát khi i = 5, tức là chỉ xuất các giá trị từ 1 đến 4
**Mã VB**
For i As Integer = 1 To 10 If i = 5 Then Exit For End If Label1.Text &= i.ToString() & "<br />" Next
**Mã C#**
for (int i = 1; i <= 10; i++) { if (i == 5) { break; } Label1.Text += i.ToString() + "<br />"; }
Có thể bỏ qua một lần lặp để chuyển qua lần lặp kế tiếp bằng lệnh Continue While, Continue Do hay Continue For (continue trong C#). Ví dụ xuất từ 1 đến 10 nhưng bỏ số 5:
**Mã VB**
For i As Integer = 1 To 10 If i = 5 Then Continue For End If Label1.Text &= i.ToString() & "<br />" Next
**Mã C#**
for (int i = 1; i <= 10; i++) { if (i == 5) { continue; } Label1.Text += i.ToString() + "<br />"; }
**Các phương thức (methods)**
Dùng để chứa các đoạn mã có thể được sử dụng nhiều lần, tại bất kì vị trí nào.
Phương thức trong VB hay C# có hai dạng là
**Function** và **Sub** (chúng giống như khái niệm hàm hay thủ tục trong C).
Cú pháp
**Function **trong VB:
PublicFunction Tên_Function ([Danh sách tham số]) As Kiểu_dữ_liệu ' Mã thực thi Return Giá_trị_trả_về End Function
Cú pháp
**Function **trong C#:
public Kiểu_dữ_liệu Tên_Function ([Danh sách tham số]) { //Mã thực thi return Giá_trị_trả_về; }
Cú pháp
**Sub **trong VB
Public Sub Tên_Sub ([Danh sách tham số]) ' Mã thực thi End Sub
Cú pháp
**Sub **trong C#
publicvoid Tên_Sub ([Danh sách tham số]) { Mã thực thi }
Sự khác biệt giữa
**Function** và **Sub** là **Function** có giá trị trả về (từ khoá **Return)** có kiểu dữ liệu là **Kiểu_dữ_liệu** của **Function.** Từ khoá **Public** định nghĩa phạm vi của phương thức. Trong **Function** hay trong **Sub** có chứa danh sách tham số hoặc không.
Ví dụ về
**Function** tính tổng hai số nguyên **Mã VB**
Public Function Add(a As Integer, b As Integer) As Integer Return a + b End Function
**Mã C#**
public int Add(int a, int b) { return a + b; }
Ví dụ
**Sub** hiển thị một thông điệp **Mã VB**
Public Sub DisplaylMessage(msg As String) MessageBox.Show(msg) End Sub
**Mã C#**
public void DisplaylMessage(string msg) { MessageBox.Show(msg); }
Trong
**Function Add** có hai tham số là a và b; nó có kiểu dữ liệu trả về là Integer và giá trị trả về là tổng a và b thông qua từ khoá **Return** có kiểu là **Integer.** **Sub DisplayMessage** có một tham số là **msg;** nó không có kiểu dữ liệu và giá trị trả về.
Trong ngôn ngữ lập trình hướng đối tượng như C# hay VB,
**Function** hay **Sub** có thể được gọi bằng một tên chung là phương thức (method).
Các tham số trong
**Function** hay **Sub** có hai hình thức là tham trị dùng từ khoá **ByVal** (hoặc không) và tham chiếu dùng tử khoá **ByRef**. Mặc định là truyền tham trị.
Khi tham số truyền tham trị, một bản sao được tạo ra. Bất kì sự thay đổi đều xảy ra trên bản sao và bản sao này sẽ bị huỷ khi phương thức ngừng thực thi do đó sẽ không ảnh hưởng đến bản gốc. Ngược lại, khi tham số được truyền theo kiểu tham chiếu thì mọi thay đổi sẽ diễn ra trên bản gốc, do đó, khi phương thức kết thúc thì bản gốc cũng bị thay đổi.
Ví dụ:
Public Sub ByValDemo(someValue As Integer) 'truyền tham trị someValue = someValue + 20 End Sub Public Sub ByRefDemo(ByRef someValue As Integer) 'truyền tham chiếu someValue = someValue + 20 End Sub Dim x As Integer = 0 ByValDemo(x) ' một bản sao của x được tạo ra và được gán giá trị 20 Label1.Text = x.ToString() ' x = 0 vì bản sao bị huỷ và bản gốc ' không thay đổi Dim y As Integer = 0 ByRefDemo(y) ' y = 20 Label1.Text = y.ToString() ' y = 20 vì bản gốc bị thay đổi đến 20
Trong C# dùng từ khoá
**ref** có chức năng tương tự **ByRef**, chỉ khác là chúng ta phải dùng từ khoá **ref** trong cả lệnh gọi **Function** hay **Sub.** Ví dụ:
public void ByRefDemo(ref int someValue) { someValue = someValue + 20; } int y = 0; ByRefDemo(ref y); // y = 20
**Thực hành **
Trong phần thực hành này, chúng ta sẽ tạo ra một ứng dụng tên Calculator thực hiện các phép toán đơn giản như +, -, *, /.
**Ứng dụng Calculator**
- Trong thư mục
**Demos**, tạo trang mới tên **CalculatorDemo.aspx**, chú ý chọn **Place code in separate file**và bỏ chọn **Select master page**.
- Chuyển trang sang chế độ
**Design**, đặt con trỏ trong vùng có viền, chọn **Table**> **Insert Table**với 3 dòng 3 cột. Kết hợp 3 ô đầu tiên của **Table**bằng cách bôi đen 3 ô này và chọn **Table**> **Modify**> **Merge Cells**.
- Thêm các controls với
**ID**và các thuộc tính như sau:
-
**Control** **ID** **Thuộc tính** Label ResultLabel Text để rỗng TextBox ValueBox1 DropDownList OperatorList Thêm 4 items là +, -, *, / TextBox ValueBox2 Button CalculateButton Thiết lập Text là Calculate
- Giao diện sẽ trông như sau:
- Trong thư mục
**App_Code**thêm một lớp mới tên **Calculator**bằng cách nhấp chuột phải và chọn **Add > Add New Item > Class**và đặt tên là **Calculator.vb**và nhấn **Add**sẽ đến giao diện như sau:
- Bổ sung code như sau:
- Trở lại trang
**CalculatorDemo**. **aspx**trong thư mục **Demos**ở chế độ **Desgin**, nhấp đôi chuột vào button **Calculate**sẽ đến giao diện code như sau:
- Thêm code vào
**Sub CalculateButton_Click**như sau:
- Lưu tất cả, chọn trang
**CalculatorDemo.aspx**và **Ctrl + F5**.
**Namespace (không gian tên)** **Namespace** là một bộ chứa (container) dùng để chứa một số lượng lớn các chức năng ( thường là lớp) trong ** .NET Framework** hay trong chương trình của bạn và chống lại tình trạng xung đột trong trường hợp chia sẻ các thành phần (lớp) có cùng tên.
Có thể truy cập các thành phần trong namspace thông bằng cú pháp:
<strong>tên_namespace.thành_phần_cần_truy_cập</strong>
Ví dụ chúng ta thấy một khai báo trong một trang aspx như sau:
**Mã VB**
Partial Class Demos_CalculatorDemo Inherits System.Web.UI.Page
**Mã C#**
public partial class Demos_CalculatorDemo : System.Web.UI.Page
Ta thấy lớp
**Demos_CalculatorDemo** thừa kế từ lớp **Page** và lớp này được chứa trong namespace **System.Web.UI**.
Các kiểu dữ liệu cũng được chứa trong namespace, ví dụ kiểu
**Double** chứa trong namespace **System** nên khi truy cập **Double** ta thường dùng **System.Double**. Hay control **Button** được chứa trong namespace **System.Web.UI.WebControls**. **Thực hành tạo namespace (VB)**
- Mở file
**Calculator.vb**đã tạo và tạo một **namspace**tên là **NgocMinh.VD**chứa lớp **Calculator**. Bổ sung đoạn mã như sau:
- Lúc này lớp
**Calculator**được chứa trong **namespace NgocMinh.VD**nên khi mở trang code VB của trang **CaculatorDemo.aspx**(tức mở file **CalculatorDemo.aspx.vb**) sẽ bị lỗi như sau:
- Lỗi trên do trình biên dịch không nhận ra lớp
**Calculator**, để khắc phục lỗi trên chúng ta phải khai báo namespace **NgocMinh.VD**bằng lệnh **ở dòng đầu tiên như sau:** *imports*
- Lưu, chọn trang
**Caculator.aspx**và **Ctrl + F5**. Kết quả giống phần thực hành trên.
**Chú thích (comment)** **Comment** là nội dung không được thực thi nhằm giải thích các đoạn mã giúp người khác có thể đọc code dễ dàng hơn hoặc có thể giúp ích trong quá trình sửa lỗi chương trình.
Chú thích trong VB bắt đầu bằng dấu nháy đơn, trong C# dùng dấu // để chú thích một dòng và dùng /*…*/ để chú thích nhiều dòng . Ví dụ: chú thích
**Mã VB**
' khai bao bien kieu Integer ' và gan gia tri là 5 Dim x As Integer = 5
**Mã C#**
// khai bao bien kieu Integer // và gan gia tri là 5 int x = 5; hay /* khai bao bien kieu Integer và gan gia tri là 5 */ int x = 5;
**Chú thích XML **có thể được thực hiện bằng cách thêm các phần tử XML. Chú thích XML bắt đầu bằng ba dấu nháy đơn **”’ **
Ví dụ
**Function Add** có thể chú thích **XML** như sau (tương tự các **Function** khác): đặt con trỏ chuột phía trên **Function Add** và gõ ba dấu nháy đơn liên tiếp sẽ xuất hiện các thẻ **XML** như **<summary>** hay **<param>.** Các thẻ **XML** cũng như các thẻ **HTML** có thẻ bắt đầu, như **<summary>,** và thẻ kết thúc, như **</summary>.**
Bổ sung các ghi chú như sau:
Điểm thú vị khi chú thích XML sẽ hiển thị khi chúng ta sử dụng
**Add** trong file **CalculatorDemo.aspx.vb** như sau:
**Cơ bản về hướng đối tượng**
Mọi thứ trong .
**NET Framework** đều là đối tượng (object), từ những kiểu dữ liệu đơn giản như **Integer** đến những thứ phức tạp như **DropDownList** control,…
**Object (đối tượng)** **Object** là khái niệm cơ bản trong lập trình hướng đối tượng (object oriented programming). Đó là một cấu trúc đóng gói dữ liệu và chức năng như một đơn vị duy nhất và chỉ có thể truy cập đối tượng thông qua giao diện của nó như thuộc tính, phương thức. Quá trình tạo một đối tượng gọi là quá trình thực thể hoá (instantiating) bằng từ khoá **New (**hay **new** trong C# **)**. Ví dụ tạo các đối tượng từ các lớp **Calculator** hay **Integer** như sau: **Mã VB**
Dim myCalculator As Calculator = New Calculator() Dim age As Integer = New Integer()
**Mã C#**
Calculator myCalculator = new Calculator(); int age = new int();
**myCalculator** và **age** được gọi là các instance (thực thể hay thể hiện) hay phổ biến hơn gọi là các object (đối tượng).
Trước khi có object cần có một định nghĩa chi tiết về object thông qua class.
**Class (lớp)**
Class giống như một bản kế hoạch chi tiết cho object. Trong ví dụ trước, chúng ta đã định nghĩa class
**Calculator** và từ lớp này có thể tạo ra nhiều thực thể (instance) hay đối tượng, ví dụ như **myCalculator** (ví dụ trên). Cú pháp tạo một class: **VB**
Public Class Tên_class ' các thành phần trong class End Class
**C#**
public class Tên_class { // các thành phần trong class }
Các thành phần trong class gồm các trường (fields), thuộc tính (properties), phương thức (methods) và phương thức
**constructor**.
**Field (trường)**
Là các đặc điểm riêng của đối tượng, ví dụ đối tượng SinhVien có các đặc điểm riêng là firstName, lastName, sex,…Định nghĩa field giống như định nghĩa biến theo cú pháp sau:
**VB**
Phạm_vi_truy_cập Tên_field As Kiểu_dữ_liệu
**C#**
Phạm_vi_truy_cập Kiểu_dữ_liệu Tên_field;
Phạm_vi_truy_cập là phạm vi truy cập của field (sẽ được đề cập phần tiếp theo), có thể là
**Private**, **Public**, **Protected** hay **Friend**. Ví dụ: **Mã VB**
Public Class Person Private firstName As String ' trường firstName với phạm vi là Private End Class
**Mã C#**
public class Person { private string firstName; //trường firstName với phạm vi là private }
Thông thường các field là các đặc điểm (hay dữ liệu) riêng tư của đối tượng và không thể truy cập trực tiếp (phạm vi truy cập
**Private).** Do đó, để truy cập các fields chúng ta dùng các thuộc tính (properties).
**Property (thuộc tính)** **Property** có thể hiểu là giao diện để có thể truy cập các trường (fields). Điều này liên quan đến một khái niệm cốt lõi trong mô hình hướng đối tượng gọi là tính đóng gói (encapsulation) hay là khả năng ẩn đi những cái phức tạp hay quan trọng của đối tượng, chỉ đưa ra giao diện cần thiết cho người dùng. Có thể hiểu khái niệm này giống như máy ATM, người dùng chỉ có thể thấy được giao diện để nhập thông tin và nhận tiền còn quá trình xử lý, cấu tạo bên trong thì không cần biết.
Trong VB, thuộc tính có thể khai báo giống như field, ngoại trừ có từ khoá
**Property**: **VB**
Public Property Tên_thuộc_tính As Kiểu_dữ_liệu
Trong C# không dùng
**Property** **C#**
public Kiểu_dữ_liệu Tên_thuộc_tính {get; set;}
Có thể dùng khối lệnh
**Get** (còn gọi là getter) để lấy dữ liệu từ các trường và khối lệnh **Set** (còn gọi là setter) để gán giá trị cho trường. Cú pháp: **VB**
Phạm_vi_truy_cập Property Tên_thuộc_tính () As Kiểu_dữ_liệu Get ' trả về giá trị của một trường nào đó với Return End Get Set (value As String) ' value phải được khai báo như là tham số của Set ' gán giá trị value cho trường End Set End Property
**C#**
Phạm_vi_truy_cập Kiểu_dữ_liệu Tên_thuộc_tính { get { // trả về giá trị của một trường nào đó với Return } set { // value không cần khai báo // gán giá trị value cho trường } }
Ví dụ lấy giá trị và gán giá trị cho trường
**firstName** của class **Person**: **Mã VB**
Public Class Person Private firstName As String Public Property FirstName() As String Get Return firstName End Get Set(value As String) firstName = value End Set End Property End Class
**Mã C#**
public class Person { private string firstName; public string FirstName { get { return firstName; } set { firstName = value; } } }
Chúng ta không thể truy cập trực tiếp đến field
**firstName** mà phải thông qua thuộc tính **FirstName**. Cụ thể: **Mã VB**
' tạo một instance của đối tượng Person Dim myPerson As Person = New Person() ' Gán giá trị cho firstName thông qua FirstName myPerson.FirstName = "Ngoc Minh" ' lấy giá trị firstName Label1.Text = myPerson.FirstName
**Mã C#**
// Tạo một instance của đối tượng Person Person myPerson = new Person(); // Gán giá trị cho firstName thông qua FirstName myPerson.FirstName = "Ngoc Minh"; // lấy giá trị firstName Label1.Text = myPerson.FirstName;
**Thuộc tính chỉ đọc (read only) và thuộc tính chỉ ghi (write only)** *** Trong VB** có thể tạo ra các **thuộc tính chỉ đọc (read onl**y) hay **chỉ ghi (write only)** theo cú pháp:
Thuộc tính chỉ đọc với từ khoá
**ReadOnly** và khối **Get**
Phạm_vi_truy_cập ReadOnly Property Tên_thuộc_tính () As Kiểu_dữ_liệu Get ' trả về giá trị của một trường nào đó với Return End Get End Property
Thuộc tính chỉ ghi với từ khoá
**WriteOnly** và khối **Set**
Phạm_vi_truy_cập WriteOnly Property Tên_thuộc_tính () As Kiểu_dữ_liệu Set (value As String) ' gán giá trị cho trường End Set End Property
*** Trong C#, **việc tạo **thuộc tính chỉ đọc** đơn giản chỉ là bỏ khối lệnh **set**, tạo **thuộc tính chỉ ghi** chỉ cần bỏ khối lệnh **get**.
**Method (phương thức)**
Nếu
**field** hay **property** là đặc điểm của đối tượng thì method là hành vi hay chức năng của đối tượng. Ví dụ đối tượng **Person** có các đặc điểm là **firstName, lastName, dateOfBirth** và phương thức là **Talk** () để giới thiệu bản thân.
Định nghĩa
**method** trong **class** giống định nghĩa **Sub** hay **Function.** Ví dụ: **Mã VB**
Public Class Person Public Sub Talk() ' code thực thi phương thức Talk End Sub End Class
**Mã C#**
public class Person { public void Talk() { // code thực thi phương thức Talk } }
**Constructor (phương thức khởi tạo)**
Là một phương thức đặc biệt, thực thi ngay khi chúng ta tạo một instance cho một object và theo sau từ khoá
**New.** Phương thức **constructor** có tên trùng với tên class. Ví dụ tạo instance của đối tượng **Calculator** như sau: **Mã VB**
Dim myCalculator As Calculator = New Calculator()
**Mã C#**
Calculator myCalculator = new Calculator();
Nếu chúng ta không định nghĩa constructor trong class thì trình biên dịch sẽ tạo một constructor mặc định. Mặc định,
**trong VB** phương thức construtor trong class tên là **New** không có tham số và không có giá trị trả về, trong C# phương thức contructor có tên trùng với tên lớp, không có tham số và không có giá trị trả về. Cú pháp: **VB**
Public Class Tên_class Public Sub New() End Sub End Class
**C#**
public class Tên_class { public Tên_class() { } }
**Quá tải constructor**
Bên cạnh constructor mặc định, chúng ta có thể định nghĩa nhiều constructor trong class và các phương thức constructor này phải có danh sách tham số khác nhau . Ví dụ class
**Person** có hai constructor, một constructor không có tham số và một constructor có một tham số trong danh sách tham số, có thể định nghĩa như sau: **Mã VB**
Public Class Person Private firstName As String ' constructor không có tham số Public Sub New () firstName = "Minh" End Sub ' constructor có tham số Public Sub New (fName As String) firstName = fName End Sub End Class
**Mã C#**
public class Person { private string firstName; // constructor không có tham số public Person () { firstName = "Minh"; } // constructor có tham số public Person (string fName) { firstName = fName; } }
Với cách định nghĩa class
**Person** như trên, chúng ta có thể có hai cách (hai phiên bản) tạo instance cho **Person:** **Mã VB**
Dim myPerson As Person = New Person() Dim myPerson As Person = New Person("Minh")
**Mã C#**
Person myPerson = new Person(); Person myPerson = new Person("Minh");
.NET cũng cung cấp cho bạn một cách khác để tạo object và khởi tạo giá trị cho thuộc tính. Cách này gọi là
**object initializer**.
Trong
**VB**, ví dụ class **Person** có thuộc tính **FirstName:**
Public Class Person Public Property FirstName As String End Class
Tạo instance của
**Person** và khởi tạo thuộc tính **FirstName** với từ khoá **With**:
Dim myPerson As New Person() With {.FirstName = "Minh" }
Chú ý: trong VB có từ khoá
**With** và dấu **.** trước thuộc tính FirstName.
Trong
**C#**, ví dụ class **Person** có thuộc tính **FirstName:**
public class Person { public string FirstName {get;set;} }
Tạo instance của
**Person** và khởi tạo thuộc tính **FirstName:**
Person myPerson = new Person(){FirstName = "Minh" };
Chú ý: trong C# không có từ khoá
**With** và dấu **.** trước thuộc tính **FirstName.**
**Inheritance (thừa kế)**
Một trong những khái niệm quan trọng và rất mạnh của mô hình hướng đối tượng, bên cạnh tính đóng gói đã đề cập ở trên, là khái niệm
**thừa kế**. Thừa kế nhằm tận dụng dữ liệu và chức năng có sẵn để phát triển, mở rộng ứng dụng ở mức cao hơn. Ví dụ các lớp Student hay Employee có thể kế thừa từ lớp Person vì chúng đều cần các đặc điểm như firstName, lastName hay phương Talk()…
Tuỳ theo phạm vi truy cập (
**Private**, **Public**, **Protected**, **Friend**) mà *các thuộc tính hay phương thức của lớp cha sẽ được kế thừa từ lớp con.* Một lớp muốn thừa kế một lớp khác phải dùng từ khoá **inherits** (trong VB) hay dấu hai **:** (trong C#) theo cú pháp: **VB**
Public Class Tên_lớp_con Inherits Tên_lớp_cha ' mã End Class
**C#**
public class Tên_lớp_con : Tên_lớp_cha { // mã }
Ví dụ lớp Student thừa kế từ lớp Person như sau:
**Mã VB**
Public Class Student Inherits Person ' mã End Class
**C#**
public class Student : Person { // mã }
Mỗi trang ASPX được tạo ra thừa kế từ lớp
**System.Web.UI.Page**, lớp này được thừa kế từ lớp **TemplateControl** được thừa kế từ lớp **Control** và **Control** thừa kế từ lớp **Object.** Ví dụ ta có trang **MyWebPage.aspx** sẽ có cây thừa kế như sau:
Lớp
**TemplateControl** ở trên gọi là **lớp cơ sở** ( **base class**), là lớp không thể được thực thể hoá, nghĩa là không thể dùng từ khoá **New** để tạo ra một instance mới.
**Polymophism (đa hình)**
Các phương thức trong lớp cha có thể có thể được thừa kế từ lớp con nếu phạm vi truy cập của nó là
**Public** hay **Protected**. Mặc khác, chúng ta có thể định nghĩa lại các phương thức được thừa kế nhờ một tính năng thú vị khác trong mô hình hướng đối tượng là **tính đa hình (polymophism)**. Ví dụ phương thức **Talk()** của lớp **Person** có thể được thừa kế và định nghĩa lại trong lớp **Student.** Muốn vậy, khi định nghĩa phương thức **Talk** trong **Person** phải có từ khoá **Overridable** (trong VB) hay **virtual** (trong C#) và phương thức **Talk** trong **Student** được định nghĩa lại với từ khoá **Overrides** (trong VB) hay **override** (trong C#), cụ thể lớp **Person:** **Mã VB**
' Lớp Person Public Class Person Public Overridable Sub Talk() 'Code thực thi End Sub End Class ' Lớp Student Public Class Student Inherits Person Public Overrides Sub Talk(msg As String) 'Code thực thi End Sub End Class
**Mã C#**
// Lớp Person public class Person { public virtual void Talk() { // Code thực thi } } // Lớp Student public class Student : Person { public override void Talk(msg As String) { // Code thực thi } }
**Phạm vi truy cập**
Các phần trên chúng ta đã đề cập đến phạm vi truy cập của các thuộc tính hay phương thức của đối tượng. Cụ thể có 4 phạm vi truy cập thể hiện qua 4 từ khoá là
**Public, Private, Protected **và **Friend (internal **trong C# **)**, có thể được mô tả như sau:
|
|VB |
|C# |
|Mô tả
|Public||public||Thuộc tính, phương thức có thể được truy cập bởi lớp sở hữu và các lớp khác.|
|Protected||protected||Thuộc tính, phương thức có thể được truy cập bởi lớp sở hữu và các lớp thừa kế nó.|
|Friend||internal||Thuộc tính, phương thức có thể được chia sẻ bởi lớp sở hữu và các lớp thừa kế và các lớp trong cùng một assembly. Một assembly là một tập hợp các files được biên dịch (như exe hay dll) chứa các code .NET có thể dùng lại.|
|Private||private||Thuộc tính, phương thức có thể được truy cập chỉ bởi lớp sở hữu.|
Ví dụ:
**Mã VB**
Public Class A Public x As Integer Private y As String Protected i As Double Protected Friend j As Date End Class Public Class B Inherits A Public Sub Init() x = 5 ' x kế thừa từ A i = 4.5 ' i kế thừa từ A j = Date.Now 'j kế thừa từ A y = "Hello" ' phát sinh lỗi vì y là Private End Sub End Class Public Class C Public Sub Test() Dim myB As New B() myB.x ' x kế thừa từ A và có phạm vi Public myB.Init()'phương thức Public của B End Sub End Class
**Mã C#**
public class A { public int x; private string y; protected double i; protected internal date j; } public class B : A { public void Init() { x = 5; // x kế thừa từ A i = 4.5; // i kế thừa từ A j = Date.Now; // j kế thừa từ A y = "Hello" ;// phát sinh lỗi vì y là Private } } public class C { public void Test() { B myB = new B(); myB.x; // x kế thừa từ A và có phạm vi Public myB.Init(); //phương thức Public của B } }
**Sự kiện (event)** **ASP.NET** là môi trường hướng sự kiện, nghĩa là các đoạn mã sẽ được thực thi dựa trên các sự kiện xuất hiện trong ứng dụng. Các sự kiện được phát sinh bởi đối tượng nào đó và được xử lí (handle) bởi đối tượng khác. Để xử lí các sự kiện, chúng ta cần bộ xử lí sự kiện (event handler). Vi dụ khi chúng ta nhấp đôi chuột vào một đối tượng **Button** trong trang aspx ở chế độ **Desgin**, Button sẽ phát sinh sự kiện **Click** và VS sẽ tạo ra bộ xử lí sự kiện **Click** với đoạn mã sau:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click End Sub
Để xem một đối tượng control có thể có sự kiện gì trong chế độ
**Design**, chúng ta có thể nhấp vào nút có hình tia chớp trong hộp **Properties** của control tương ứng, như hình:
**Xử lí ngoại lệ (exception handling)**
Khi lập trình, chúng ta thường gặp một số kiểu lỗi sau:
**Lỗi cú pháp**(syntax errors): gõ sai chính tả, thiếu từ khoá, mã không chính xác. Thường có một số dấu hiệu trong **VS**để cảnh báo đoạn code của chúng ta bị lỗi cú pháp, thường là các đường gợn sóng xanh như hình dưới: **Lỗi logic (logical errors)**: thường là do thuật toán sai; chương trình vẫn chạy bình thường nhưng tạo ra các kết quả không mong muốn hay mong đợi. Ví dụ đoạn code sau nhầm lẫn vị trí giữa hai biến **toAddress**và **fromAddress,**và lỗi này sẽ khó phát hiện trong chương trình có hàng trăm dòng mã: **Mã VB**
Dim fromAddress As String = "you@example.com" Dim toAddress As String = EmailAddress.Text myMessage.From = New MailAddress(toAddress) myMessage.To.Add(New MailAddress(fromAddress))
**Mã C#**
string fromAddress = "you@example.com"; string toAddress = EmailAddress.Text; myMessage.From = new MailAddress(toAddress); myMessage.To.Add(new MailAddress(fromAddress));
**Lỗi Runtime (Runtime errors)**: xuất hiện trong thời gian chạy chương trình. Lỗi nay thường khó phát hiện và cần một chiến lược để xử lí.
**Phát hiện và xử lí ngoại lệ (catching and handling exceptions)**
Ngoại lệ là các lỗi không như mong đợi và khi chúng xảy ra người dùng sẽ nhận được một thông điệp. Lớp ngoại lệ trong .NET thừa kế từ lớp cơ sở (base class)
**System.Exception**.
Kĩ thuật phổ biến để phát hiện và xử lí các ngoại lệ là dùng lệnh khối lệnh
**Try..Catch..Finally** theo cú pháp: **VB**
Try khối lệnh để kiểm tra Catch err As Exception Khối lệnh sẽ thực thi khi phát hiện lỗi từ Try Finally Khối lệnh sẽ thực thi mà không quan tâm kết quả từ Try/Catch End Try
**C#**
try { khối lệnh để kiểm tra } catch (Exception err) { Khối lệnh sẽ thực thi khi phát hiện lỗi từ Try } finally { Khối lệnh sẽ thực thi mà không quan tâm kết quả từ Try/Catch }
Ví dụ:
**Mã VB**
Dim userMessage As String = String.Empty Try mySmtpClient.Send(myMessage) userMessage = "Message sent" Catch ex As Exception userMessage = "An unknown error occurred." Finally Message.Text = userMessage End Try
**Mã C#**
string userMessage = string.Empty; try { mySmtpClient.Send(myMessage); userMessage = "Message sent"; } catch (Exception err) { userMessage = "An unknown error occurred."; } finally { Message.Text = userMessage; }
Thực hành dưới đây minh hoạ trong quá trình gửi mail có thể phát sinh lỗi (chẳng hạn như
**Mail Server** bị hỏng) thì một thông báo sẽ phát sinh để tránh hỏng toàn bộ ứng dụng. **Thực hành phát hiện và xử lí ngoại lệ (VB)**
- Tạo một trang tên
**ExceptionHandling.aspx**trong thư mục **Demos**, chọn template là **MyBasePage**(do chúng ta tạo ra trong chương trước) và thiết lập thuộc tính **Title**là **Exception Handling Demo**.
- Thêm một
**Label**đến vùng **cpMainContent**và thiết lập thuộc tính **ID**của nó là **Message**
- Chuyển trang đến chế độ
**Design**và chọn sự kiện **Load**của trang bằng cách nhấp đôi chuột vào một vị trí bất kì trong trang. Bổ sung thêm dòng mã **Imports System.Net.Mail**vào đầu file code VB ( **ExceptionHandling.aspx.vb**):
- Thêm code vào
**Sub Page_Load**như sau:
- Lưu, chọn trang
**ExceptionHandling.aspx**và **Ctrl + F5**sẽ xuất hiện lỗi sau:
- Để tránh lỗi này, trở lại file
**ExceptionHandling.aspx.vb**và dùng khối **Try..Catch**cho đoạn mã như sau:
- Lưu, chọn trang
**ExceptionHandling.aspx**và **Ctrl + F5**sẽ như sau:
**Tìm và xử lí lỗi (debugging)**
Debugging là quá trình tìm và xử lí lỗi trong ứng dụng. Quá trình tìm và xử lí lỗi là phức tạp, đòi hỏi nhiều kĩ thuật.
**VS** cung cấp cho chúng ta nhiều công cụ để **debugging** được dễ dàng hơn. **Thiết lập điểm dừng (breakpoint)**
Một kĩ thuật phổ biến trong
**debugging** là thiết lập điểm dừng. Bằng cách này, VS sẽ dừng thực thi ứng dụng ngay tại dòng code mà bạn thiết lập **breakpoint**. Để làm điều này, chúng ta chỉ cần chọn dòng code và nhấn **F9** (hay nhấp chuột vào dấu chấm lớn ở lề trái của dòng code hay vào **Debug > Toggle Breakpoint**). Để xoá tất cả các **breakpoint** trên toàn website, ta nhấn **Ctrl + Shift + F9**. Để rõ hơn về kĩ thuật **breakpoint**, chúng ta sẽ thực hiện bài thực hành đơn giản dưới đây trên trình duyệt **Chrome**. **Thực hành thiết lập breakpoint (VB)**
- Mở file
**CalculatorDemo.aspx.vb**trong thư mục **Demos**
- Chọn dòng mã đầu tiên trong bộ xử lí sự kiện
**CalculateButton_Click**(kiểm tra chiều dài hai textbox). Nhấn **F9**để thiết lập **breakpoint.**Dòng mã thiết lập **breakpoint**sẽ có màu đỏ như sau:
- Nhấn
**F5**(lưu ý là **F5**chứ không phải là **Ctrl + F5**) hay vào **Debug > Start Debugging**để bắt đầu quá trình **debugging**sẽ xuất hiện hộp thoại sau:
- Nhấp
**OK**để **VS**chỉnh sửa file **Web.config**. (Lưu ý nếu chúng ta sử dụng trình duyệt **IE**thì sẽ xuất hiện thêm hộp thoại yêu cầu cho phép **Script Debugging**thì thực hiện theo hướng dẫn, trở lại **VS**và nhấp nút **Yes**).
- Trang sẽ hiển thị bình thường. Nhập
**5**vào **textbox**thứ nhất và **7**vào **textbox**thứ hai, chọn phép toán **+**và nhấn nút **Calculate**thì, thay vì hiển thị kết quả, bạn sẽ được chuyển tới môi trường **VS.**
- Dòng mã được thiết lập
**breakpoint**bây giờ sẽ trở thành màu vàng và có một dấu mũi tên ở lề bên trái. Lúc này chúng ta có thể nhìn lướt qua các biến, các controls,… Có thể xem giá trị của các **TextBox**bằng cách đưa con trỏ chuột lướt qua thuộc tính **Text**như hình dưới:
- Lưu ý rằng khi chúng ta lướt con trỏ chuột qua các control thì sẽ hiển thị các tooltip, nhưng khi lướt qua các biến như
**result**hay **value1**hay **value2**thì sẽ không có tooltip vì lúc này chương trình vẫn chưa thực thi tới nơi mà các biến này được khai báo.Nhấn **F10**để thực thi các dòng mã kể từ dòng mã được thiết lập breakpoint. Nhấn **F10**và giữ cho tới đoạn code khai báo biến **value2**có màu vàng (nghĩa là cho thực thi tới dòng code khai báo biến value2 thì dừng). Bây giờ, nếu ta rê chuột qua biến **value1**thì sẽ xuất hiện tooltip value1 5.0.
- Lướt chuột đến thuộc tính
**SelectedValue**của **DropDownList**sẽ xuất hiện tooltip là giá trị được chọn trong **DropDownList**(phép **+**):
- Chọn dòng code gán giá trị vào
**ResultLabel.Text**và nhấp chuột phải chọn **Run to Cursor**để thực hiện tất cả các dòng code từ dòng breakpoint đến dòng code hiện tại đang chọn. Lướt chuột đến biến **Result**thì hiển thị tooltip với giá trị **12**. **0**
- Nhấn
**F5**để **VS**tìm đoạn code có thiết lập điểm dừng kế tiếp, nhưng chúng ta không thiết lập thêm điểm dừng nào nên toàn bộ code trong sự kiện **Click**sẽ được thực thi và kết quả sẽ được trả lại trong trình duyệt.
**Công cụ hỗ trợ Debugging** **Visual Studio** hỗ trợ bạn một số lớn các công cụ (các phím tắt, cửa sổ,…) giúp bạn có thể tìm và xử lí lỗi một cách hiệu quả nhất.
Khi bạn dùng kĩ thuật
*điểm dừng (breakpoint),* sẽ có một số các phím tắt được hỗ trợ để giúp bạn khai thác hiệu quả kĩ thuật này (bài thực hành trên chúng ta đã dùng **F5** và **F10**). Dưới đây là một số phím được hỗ trợ:
|
|Phím |
|Chức năng
|
|F5 |Bắt đầu quá trình
|debugging.
|
|F11 |Thực thi dòng code hiện tại và có thể thực thi code bên trong nếu có (ví dụ khi thực hiện dòng lệnh, nếu bắt gặp một phương thức nào đó, ví dụ
|Add, thì VS sẽ chuyển đến phương thức Add để thực thi).
|
|F10 |Thực thi dòng code hiện tại nhưng không thực thi code bên trong trừ khi có một đoạn mã được thiết lập điểm dừng khác (nếu bắt gặp phương thức
|Add thì VS sẽ nhảy tới kết quả cuối cùng).
|
|Shift + F11 |Hoàn thành khối mã hiện tại và nhảy trở lại đoạn code đã gọi nó (ví dụ đang ở trong phương thức Add, nếu nhấn tổ hợp phím này thì VS sẽ thoát khỏi
|Add và trở lại đoạn code đã gọi Add).
|
|Shift + F5 |Ngừng debugging.|
|
|Ctrl + Shift + F5 |Khởi động lại quá trình debugging.|
Các phím trên sẽ có những biểu tượng tương ứng trên thanh công cụ như hình sau:
**Các cửa sổ hỗ trợ debugging**
VS hỗ trợ nhiều cửa sổ để chúng ta có thể xem các biến và sự thay đổi của chúng trong quá trình thực thi nhờ đó cung cấp chúng ta nhiều thông tin hơn. Để hiển thị các cửa sổ này, chúng ta vào
**Debug > Windows**, chú ý rằng một vài cửa sổ chỉ hiển thị trong quá trình debugging. Danh sách các cửa sổ gồm:
|
|Cửa sổ |
|Chức năng
|
|Watch |Là cửa sổ quan trọng nhất, giúp quan sát các biến trong quá trình thực thi.|
|
|Autos |Hợp lệ với các phiên bản thương mại của VS. Chức năng tương tự
|Watch. Hiển thị tất cả các biến mà đoạn code hiện tại và trước đó sử dụng.
|
|Local |Tương tự
|Watch và Autos, nhưng cửa sổ này chỉ hiển thị các biến trong phạm vi mà đoạn code hiện tại có thể dùng.
|
|Breakpoints |Trong các phiên bản thương mại, cho phép ta thấy tất cả các điểm dừng mà ta đã thiết lập.|
|
|Call Stack |Cung cấp thông tin về thứ tự của đoạn code được thực thi hoặc được gọi.|
|
|Immediate |Cho phép chúng ta kiểm tra nhanh code giống như ta đang thực thi trong trang.|**Thực hành với các cửa sổ debugging (VB)**
Trong bài thực hành này chúng ta sẽ làm quen với hai cửa sổ quan trọng nhất là
**Watch, Locals, Call Stack** và **Immediate**.
- Mở file
**CalculatorDemo.aspx.vb**và thiết lập breakpoint tại dòng mã khai báo biến **value1**. Nhấn **F5**để bắt đầu quá trình debugging. Nhập **5**vào textbox đầu tiên, **7**vào textbox thứ hai, chọn phép **+**và nhấn nút **Calculate**để trở lại cửa sổ **VS**.
- Rê con trỏ chuột qua biến
**OperatorList**sẽ thấy tooltip xuất hiện. Để ý rằng có một dấu **+**bên trái tooltip cho phép chúng ta mở rộng để hiển thị thêm thông tin về biến:
- Nhấp chuột phải vào biến
**value1**trong lệnh **If**kiểm tra chiều dài chuỗi trong textbox và chọn **Add Watch**. Bây giờ chúng ta có thể xem thông tin về biến **value1**trong cửa sổ **Watch**giống như trong tooltip. Cuộn cửa sổ đến thuộc tính **Text**của sẽ thấy giá trị 5:
- Nhấp đôi chuột vào “5” và thay bằng “12”, nhấn Enter.
- Mở cửa sổ
**Locals**bằng cách vào **Debug > Windows > Locals**:
- Để ý giá trị của
**value1**trên **Locals**lúc này là **0.0**. Nhấn **F10**để thực thi đoạn mã thiết lập breakpoint (tức là thực hiện việc lấy giá trị từ textbox1, đổi sang **Double**và gán cho **value1**), lúc này giá trị **value1**là **12.0**và có màu đỏ (giá trị chúng ta nhập ở trên):
- Lưu ý rằng việc thay đổi giá trị
**value1**chỉ diễn ra trên server, không ảnh hưởng đến trình duyệt, nên giá trị trên trình duyệt lúc này vẫn là 5.
- Nhấn
**F10**thực hiện lệnh gán giá trị cho **value2**, lúc này **value2**sẽ chuyển sang đỏ trong cửa sổ **Locals**và **value1**sẽ trở lại màu đen:
- Nhấn
**F10**thực hiện các dòng lệnh cho tới lệnh **Case**gọi phương thức **Add**(tức là khi dòng mã này có màu vàng). Tới đây, nếu chúng ta tiếp tục nhấn **F10**thì VS sẽ thực thi phương thức **Add**và gán giá trị vào biến **result**, sau đó nhảy đến lệnh gán giá trị biến **result**đến thuộc tính **Text**của Thay vì nhấn **F10**để xem kết quả thì chúng ta có thể xem chi tiết code bên trong phương thức **Add**bằng cách chuyển đến phương thức này với phím **F11**. Bên trong **Add**chúng ta có thể rê chuột để xem giá trị của các tham số trong **Add**:
- Mở cửa sổ
**Call Stack**bằng cách vào **Debug > Windows > Call Stack**và chúng ta thấy phương thức **Add**được gọi bởi bộ xử lí sự kiện **CalculateButton_Click**:
- Nhấp đôi chuột vào dòng thứ hai trong cửa sổ
**Call Stack**, sẽ nhảy đến file **CalculatorDemo.aspx.vb**và dòng mã gọi phương thức **Add**sẽ có màu xanh. Lưu ý ở đây không thực hiện bất cứ dòng mã nào:
- Nhấp lại dòng đầu tiên trong
**Call Stack**sẽ trở lại phương thức **Add**.
- Bấm
**Shift + F11**để thoát khỏi phương thức **Add**và trở lại đoạn mã đã gọi nó, lúc này các dòng mã trong cửa sổ **Call Stack**về phương thức **Add**đã biến mất:
- Lúc này biến
**result**vẫn chưa có giá trị vì đoạn code này vẫn chưa thực thi.
- Mở cửa sổ
**Immediate**bằng cách vào **Debug** **>** **Windows** **>** **Immediate**để kiểm tra nhanh vài lệnh. Gõ lệnh sau trong cửa sổ và **Enter**:
? New Calculator().Multiply(4, 12)
Trong cửa sổ
**Immediate** sẽ hiển thị kết quả:
- Nhấn
**F10**để thực thi code hiện tại. Lúc này, mũi tên màu vàng sẽ nhảy đến cuối khối lệnh **Select..Case**
- Nhấp và rê chuột đưa mũi tên màu vàng trở lại lệnh
**myCalculator.Add**:
- Việc này để yêu cầu VS thực thi lại đoạn mã nếu nhấn F10 hoặc vào phương thức
**Add**nếu nhấn **F11**.
- Nhấn
**F5**hiển thị kết quả trên trình duyệt:
**Debugging với Page Inspector**
Là công cụ debugging mới được tích hợp trong VS 2012, mang lại trải nghiệm hợp nhất giữa trình duyệt, ASP.NET run time và source code. Công cụ này tương tự
**FireBug** trong **FireFox** hay **IE**, **Chrome** **Developer**, nhưng có điều đặc biệt là nó có thể tạo mối quan hệ hai chiều giữa mã client (HTML, CSS, Script) trên trình duyệt và mã ASP.NET. Nó cho phép chúng ta tạo trên IDE, chỉnh sửa và xem trước kết quả.
Điều kiện dùng
**Page Inspector**:
- Cài phiên bản IE 9 trở lên.
- Dùng
**.NET 4.0**trở lên.
- Hoạt động trong chế độ Debug và thêm thông tin vào
**Web.config**cho phép **Page Inspector**hoạt động. **Thực hành dùng Page Inspector (VB)**
- Chọn trang
**CalculatorDemo.aspx**. Trên thanh công cụ tại danh sách **Target Browser**(nơi có tên trình duyệt như **Google Chrome**hay **Internet Explorer**), nhấp mũi tên hướng xuống bên phải, chọn **Page Inspector**:
- Nhấn
**F5**để bắt đầu **debugging**, sau vài giây **Page Inspector**sẽ xuất hiện trong VS như sau:
- Đóng hết tất cả các cửa sổ (bao gồm cả
**Solution** **Explorer**) chỉ để lại cửa sổ **Page** **Inspector**. Hai nút gốc trái trên **Page Inspector**là **Browser**để hiển thị trang như trong trình duyệt, **Problems**cho biết thông tin lỗi trang với số lỗi bên cạnh (trong trường hợp này là 0 vì không có lỗi):
- Phía dưới chúng ta có hai màn hình chứa các nút. Bên trái gồm nút
**HTML**để hiển thị mã **HTML,**nút **Inspect**để dò tìm các phần tử trong trang và nút **Files**hiển thị file trên server:
- Nhấn nút
**Inspector**và rê con trỏ chuột đến phần tử bất kì trong trang, ví dụ **textbox1**thì mã của textbox này sẽ phát sinh tương ứng bên dưới:
- Trong cửa sổ code bên phải, tìm đến
**DropDownList**và trong **ListItem**thử thay đổi dấu **+**bằng một đoạn text bất kì thì sẽ xuất hiện cảnh báo:
- Bấm
**Ctrl + Alt + Enter**để reload trang lại. Lúc này, dòng text vừa gõ sẽ thay thế dấu **+**trong **DropDownList**:
- Cửa sổ các nút bên phải như
**Styles**, **Trace Styles**, **Layout**và **Attribute**cho phép chúng ta theo dõi thông tin về **CSS,**các thuộc tính của các phần tử trong trang.
**Debugging với tracing (tìm vết)** **Tracing** là khả năng tìm vết để theo dõi các thành phần trong trang aspx hay toàn bộ site. **Tracing** được tích hợp sẵn trong **ASP.NET Framework**. **Tracing một trang aspx**
Để tracing một trang nào đó, ta cần mở trang trong chế độ
**Source**, tìm đến **<Page>** và thêm thuộc tính **Trace**:
<%@ Page ........ Trace="true" %>
Khi chúng ta cho phép chức năng
**trace** trong một trang bất kì thì khi thực thi trang trên trình duyệt sẽ xuất hiện các thông tin kèm theo, ví dụ trang **CalculatorDemo.aspx**: **Tracing toàn bộ site (áp dụng cho toàn bộ trang trong site)**
Thêm phần tử
** <trace />** vào trong **<system.web>** trong file **Web.config**. Một số thuộc tính quan trọng kèm theo phần tử **trace:**
|
|Thuộc tính |
|Chức năng
|
|enabled |Cho phép chức năng trace hoặc không.|
|
|traceMode |Thay đổi thứ tự sắp xếp các thành phần trong bảng thông tin hiển thị trên trình duyệt.|
|
|requestLimit |Xác định số trace yêu cầu hợp lệ.|
|
|pageOutput |Cho phép thông tin hiển thị trên trình duyệt hay không.|
|
|localOnly |Cho phép trình xử lí Trace.axd được truy cập từ host cục bộ.|
|
|mostRecent |Lấy những thông tin của yêu cầu trace gần nhất.|**Thực hành với tracing (VB)**
- Mở
**Web.config**và thêm phần tử <trace /> với các thuộc tính kèm theo vào trong phần tử <system.web> như sau:
- Mở trang
**aspx**và **Ctrl + F5**:
- Thông tin về trang sẽ hiển thị và chúng ta có thể tìm hiểu các thông tin cần thiết.
- Trên thanh địa chỉ của trình duyệt, gõ thông tin sau để yêu cầu trình xử lí
**axd**:
- Kết quả sẽ cho thông tin sau trên trình duyệt:
**Thêm thông tin đến trace**
Chúng ta có thể thêm thông tin cá nhân đến trace để tiện theo dõi các thành phần trong ứng dụng. Để làm điều này, chúng ta dùng lớp
**Trace** với hai phương thức cơ bản là **Write** và **Warn.** **Thực hành thêm thông tin vào trace (VB)**
- Mở file
**CalculatorDemo.aspx.vb**, trong trình xử lí sự kiện Click, chúng ta thêm đoạn code **Trace.Write**ở trên câu lệnh **Select Case**như sau:
- Thêm câu lệnh
**Trace.Warn**vào lệnh **Else**:
- Lưu và trở lại trang
**CalculatorDemo.aspx**, **Ctrl + F5**. Nhập thông tin vào textbox1 và textbox2 ta sẽ thấy xuât hiện dòng thông tin trong lệnh **Trace.Write**ở giữa **Begin Raise PostBackEvent**và **End Raise PostBackEvent**:
- Xoá các thông tin trong một hoặc cả hai textbox và nhấn nút
**Calculate**sẽ xuất hiện cảnh báo trong lệnh **Warn**:
- Trở lại
**VS**và **Stop Debugging**. **Cảnh báo**: Vì tính bảo mật nên bạn không nên lạm dụng trace mà luôn luôn thiết lập thuộc tính **enabled** đến **false** hoặc **localOnly** đến **true**.
## Ý kiến bài viết Hủy trả lời

WARC-Identified-Payload-Type: text/html

Server: nginx

Vary: Cookie

X-hacker: If you're reading this, you should visit automattic.com/jobs and apply to join the fun, mention this header.

X-ac: 3.dca _dca