Documentos de Académico
Documentos de Profesional
Documentos de Cultura
UI TP
RO
-1-
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 1
LẬP TRÌNH C#.NET
-2-
NGUYỄN TRẦN MINH KHUÊ
Visual C# .NET là thành viên mới nhất của dòng sản phẩm Visual Studio, đây
là ngôn ngữ lập trình mới dựa trên ngôn ngữ lập trình C/C++ nhưng mở rộng
cho phép lập trình hướng đối tượng dể dàng hơn. Cú pháp của C# tương tự như
cú pháp của ngôn ngữ lập trình C/C++ chính vì vậy rất quen thuộc với các bạn
đã có kiến thức về ngôn ngữ lập trình C/C++ hay Java.
Trong chương này chúng ta tìm hiểu về thế giới Microsoft .NET và cấu trúc
của chương trình viết bằng ngôn ngữ C#.
Các vấn đề chính sẽ được đề cập:
- Giới thiệu về Microsoft .NET.
- Cơ chế biên dịch và thực thi của chương trình .NET.
- Cấu trúc chương trình C#.
- Tạo mới hay mở ứng dụng C#.
- Biên dịch và thực thi chương trình C#.
-3-
NGUYỄN TRẦN MINH KHUÊ
Internet Protocol
Microsoft .NET được xây dựng dựa trên những nghi thức mạng đang tồn
tại như HTTP và SOAP (Simple Object Access Prototcol). Trong đó, SOAP là
nghi thức kết từ XML/HTTP.
SOAP là nghi thức cho phép truy cập thiết bị, đối tượng và máy chủ trên
nhiều nền độc lập. Ngoài ra, nghi thức SOAP sử dụng để trao đổi thông tin giữa
các máy tính trung tâm và các máy tính vệ tinh.
.NET Platform cho phép nhà lập trình phát triển ứng dụng sử dụng các
ngôn ngữ lập trình khác nhau và chạy trên nền Windows. Hệ điều hành Windows
(CE, ME, 2000 và 2003) là tầng cuối cùng, trong khi đó tầng giữa bao gồm .NET
Framework, .NET Enterprise Servers và Building Block Services.
1.1.1. .NET Framework
NET Framework bao gồm Common Language Runtime (CLR), các lớp cơ
sở (Base classes), dữ liệu và XML (Data and XML), dịch vụ Web (Web
Services) và giao diện người sử dụng (Web UI).
1.1.2. .NET Enterprise Servers
.NET Enterprise Servers là dòng server cho phép chúng ta xây dựng và
quản lý các tương tác các hệ thống bao gồm: SQL Server 2000, Host Integration
Server, Internet Security & Acceleration Server 2000 (ISA), Exchange 2000
Server & Exchange Server 2000 Conferencing Server, Commerce Server 2000,
BizTalk Server 2000 và Application Server 2000.
1.1.3. Building Block Services
Building Block Services cung cấp các dịch vụ cho phép chúng ta tạo các
dịch vụ thương mại như Message, Calendar, Email và các dịch vụ khác.
1.2. Microsoft .NET Products and Services
Microsoft .NET Products and Services bao gồm các sản phẩm:
Windows.NET, MSN.NET, VS.NET, Office.NET và Center Server for .NET.
Trong đó, VS.NET gồm 4 ngôn ngữ lập trình chính như Visual
Basic.NET, C#, C++.NET, J# cho phép chúng ta phát triển ứng dụng Desktop
hay Web.
1.3. 3rd Party .NET Services
3rd Party .NET Services là những dịch vụ do các nhà cung cấp thứ ba phát
triển dùng để tương tác với Microsoft.NET.
2. CƠ CHẾ BIÊN DỊCH VÀ THỰC THI CỦA CHƯƠNG TRÌNH .NET
Hai ngôn ngữ lập trình chính thường được sử dụng là C++ và Visual
Basic, mã chương trình được viết và biên dịch bởi trình biên dịch (compiler) của
-4-
NGUYỄN TRẦN MINH KHUÊ
từng ngôn ngữ, mỗi ngôn ngữ có một trình thi hành (runtime) cho chính nó để
thực thi mã thực thi được tạo ra. Điều này có nghĩa là mỗi ngôn ngữ phải có trình
biên dịch và runtime cho chính nó như hình 1-1.
Runtime
C++
Executable
Code
Compiler
Code
Compiler Executed
Executable
Code
VB Runtime
C#
Compiler
C Code
Compiler R Executed
IL L
VB
Hình 1-2: Biên dịch và thực thi chương trình trong .NET
Như vậy, ứng dụng viết bằng ngôn ngữ hỗ trợ .NET được biên dịch ra IL
bằng trình biên dịch tương ứng như trình bày ở trên, chúng ta nhận được tập tin
PE (Portable Executable) chứa đựng IL.
-5-
NGUYỄN TRẦN MINH KHUÊ
.NET
Source IL
Code CRL
Code Machine
Biên dịch lần 1 Executed Code
Khi chương trình được thực thi CRL biên dịch chúng ta thành mã máy
trước khi thực hiện. Điều này có nghĩa là đoạn chương trình viết trong .NET
được biên dịch hai lần và lần biên dịch thứ nhất chậm hơn lần biên dịch thứ hai
do IL được tạo ra trong lần biên dịch thứ nhất gần với mã máy như mô tả trong
hình 1-3.
Trong phần biên dịch và thực thi chương trình .NET, hai thành phần chính
là IL và CRL được trình bày như sau:
2.1. IL
IL hay MSIL là ngôn ngữ hỗ trợ thao tác giữa các thành phần, nó gần
giống với mã nhị phân và được định nghĩa như một tập lệnh dễ dàng chuyển sang
mã máy bằng CRL.
2.2. CRL
CRL là ngôn ngữ dùng để biên dịch IL ra mã máy và nó có vai trò quản lý
bộ nhớ, biên dịch một lần có thể chạy trên hệ điều hành bất kỳ hay CPU có hỗ trợ
runtime.
Lưu ý rằng, CRL for Linux đang được phát triển cho phép chương trình
của .NET có thể chạy trên máy cài đặt hệ điều hành Linux.
3. CẤU TRÚC CHƯƠNG TRÌNH C#.
Microsoft.NET được biết đến như một thế hệ dịch vụ Windows kế tiếp
và .NET Platform hỗ trợ trên 20 ngôn ngữ khác nhau. Trình biên dịch C# là một
trong những trình biên dịch hiệu qiả nhất trong dòng sản phẩm .NET.
C# xem như một ngôn ngữ lập trình thay thế C++, bởi vì nó cung cấp hầu
hết tính năng mạnh mà trước đây chỉ có trong C++. Mặc dù có nhiều ngôn ngữ
-6-
NGUYỄN TRẦN MINH KHUÊ
lập trình trong bộ .NET, nhưng C# được xem như một Platform mới cho phép
sinh viên tham khảo để phát triển ứng dụng Desktop hay Web.
Mặc khác, C# cung cấp một kỹ thuật được gọi là người thu thập cho quá
trình tìm kiếm và tự động xoá tài nguyên được chiếm bởi các đối tượng đã huỷ.
Ngoài ra, C# là ngôn ngữ lập trình hướng đối tượng hoàn toàn, thừa
hưởng lại những gì mà ngôn ngữ C/C++ đang có và tăng thêm những đặt tính
mới cho phép sử dụng lại mà vẫn giữ được tính dễ sử dụng của ngôn ngữ lập
trình Visual Basic.
Cấu trúc của class viết bằng ngôn ngữ lập trình C# như sau:
01 /* Chương trình cơ bản của C#*/
02 using System;
03 class csharp
04 {
05 static void Main(string[] args)
06 {
07 Console.WriteLine(“Hello C Sharp”); 08
Console.ReadLine();
09 }
10 }
Dòng 01 trình bày chuỗi khai báo ghi chú được đóng và mở bởi cặp dấu /*
và */.
Dòng 02 khai báo sử dụng không gian tên System bằng cách sử dụng từ
khoá using, không gian tên System chứa hầu hết các đối tượng cho phép bạn xây
dựng ứng dụng bằng C#.
Dòng 03 là tên của lớp (class) được bắt đầu bởi từ khoá class và kế đến
tên của lớp.
Dòng 04 là dấu mở đầu của một class hay phương thức.
Dòng 05 là tên của phương thức khởi động của chương trình, mỗi chương
trình viết bằng C# phải có một phương thức khởi động được gọi là Main (có thể
có tham số Main(string[] args)) thuộc thành viên static và có tầm vực là public,
chúng ta sẽ tìm hiểu các từ khoá này trong các chương kế tiếp.
Dòng 06 là dấu mở đầu của một phương thức.
Dòng 07 dùng phương thức WriteLine của đối tượng Console trong không
gian tên System để in ra chuỗi “Hello C Sharp” trên màn hình Command Prompt.
Dòng 08 dùng phương thức ReadLine của đối tượng Console trong không
gian tên System để nhận chuỗi nhập từ bàn phím trên màn hình Command
Prompt. Trong trường hợp này chờ cho người sử dụng nhấn phím enter để kết
thúc chương trình.
Dòng 09 là dấu đóng kết thúc của một phương thức.
Dòng 10 là dấu đóng kết thúc của một lớp.
-7-
NGUYỄN TRẦN MINH KHUÊ
Lưu ý rằng, class của C# có tên mở rộng là .cs, tên của tập tin của class có
thể khác với tên của class khai báo trong class. Chẳng hạn, bạn khai báo class có
tên là clsFirstCSharp nhưng tên tập tin class là Class1.cs.
4. TẠO MỚI HAY MỞ ỨNG DỤNG C#
Để viết chương trình C# bạn có thể sử dụng Visual Studio.NET hoặc dùng
một trình soạn thảo văn bản bất kỳ. Nếu như sử dụng trình Visual Studio.NET
bạn sẽ lưu dự án (project) với tên mở rộng .csproj.
Khi tạo mới project, bạn bắt đầu Start | Microsoft Visual Studio .NET
2003 | Microsoft Visual Studio .NET 2003, cửa sổ xuất hiện như hình 1-4.
Nếu mở một porject đang tồn tại, bạn chọn File | Open | Project hoặc nhấn
tổ hợp phím Ctrl+Shifl + O, cửa sổ xuất hiện như hình 1-5. Bằng cách chọn tên
project trong phần File name và nhấn nút Open.
Nếu trước đó đang mở một project khác, bạn có thể mở tiếp project khác
cùng tồn tại thì chọn vào tuỳ chọn Add to Solution. Trong trường hợp bạn muốn
đóng project đang mở để mở project khác thì chọn vào tuỳ chọn Close Solution.
-8-
NGUYỄN TRẦN MINH KHUÊ
Chú ý rằng, nếu lần đầu tiên mở Visual Studio.NET thì hai tuỳ chọn Add
to Solution, Close Solution không tồn tại.
Trong trường hợp tạo mới project bạn chọn File| New | Project hoặc tổ
hợp phím Ctrl + Shifl + N, cửa sổ mở mới project xuất hiện như hình 1-6.
Bước kế tiếp, nhập vị trí lưu trữ project và tên của project trong phần
Name và Location. Nếu chọn ngôn ngữ lập trình C# thì bạn chọn vào Visual C#
Projects trong phần Project Types và loại ứng dụng trong phần Templates.
Visual Studio.NET cung cấp các loại Templates cho phép bạn tạo ứng
dụng Windows Forms (ứng dụng chạy trên máy để bàn), Class Library (tạo DLL
và COM+), ASP.NET Web Application (ứng dụng Web), ASP.NET Mobile Web
Application (ứng dụng Web trên Mobile), Console Application (ứng dụng màn
hình và bàn phím), ASP.NET Web Services (dịch vụ Web), Windows Services
(dịch vụ Windows), ...
Tương tự như trường hợp mở project đang tồn tại, nếu lần đầu tiên mở
Visual Studio.NET thì hai tuỳ chọn Add to Solution, Close Solution không tồn
tại.
-9-
NGUYỄN TRẦN MINH KHUÊ
Lưu ý rằng, một Solution có thể có nhiều project và một hay nhiều project
trong Solution có thể là project khởi động. Để làm điều này bạn chọn vào tên
project | R-Click | Set as Startup project hoặc khai báo trong cửa sổ thuộc tính
của Solution (Project | Properties).
Bạn có thể khai báo tất cả các class chung trong một tập tin .cs thay vì một
porject, chẳng hạn sử dụng Notepad để khai báo tập tin .cs như sau:
- 10 -
NGUYỄN TRẦN MINH KHUÊ
Tuy nhiên, bạn có thể sử dụng Visual Studio.NET để tạo project, khi đó
có nhiều class thuộc một project (namespace cùng tên với tên project) như hình
1-7.
Khi sử dụng project để khai báo class, bạn có thể tạo một tập tin .cs với
hai class trên. Tuy nhiên trong trường hợp này có thể sử dụng hai tập tin class
trong một project và cả hai class này cùng chung một namespace (chúng ta sẽ
tham khảo trong chương không gian tên) như ví dụ sau:
namespace FirstCSharp
{
/*Class thứ hai với tên tập tin Class2.cs*/
public class Class2
{
- 11 -
NGUYỄN TRẦN MINH KHUÊ
Nếu biên dịch thành công, kết quả thông báo như sau:
Microsoft (R) Visual C# .NET Compiler
version 7.10.3052.4 for Microsoft (R)
.NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002.
All rights reserved.
Trong trường hợp sử dụng Visual Studio.NET, để biên dịch project bạn
chọn vào menu có tên Build | Build Projectname. Nếu muốn biên dịch những
project trong một Solution, bạn chọn vào Build | SolutionName.
Sau khi biên dịch project thành công, trong thư mục của project xuất hiện
hai thư mục bin và obj, bạn có thể tìm thấy tập tin exe trong thư mục bin\debug
như hình 1-9.
- 12 -
NGUYỄN TRẦN MINH KHUÊ
Sau khi biên dịch thành công, bạn có thể thực thi tập tin exe này bằng
cách gọi trực tiếp từ Command Prompt hay từ Shortcut của Windows.
Tuy nhiên, trong trường hợp sử dụng Visual Studio.NET, bạn có thể chạy
thử chương trình bằng cách chọn nút Start hay F5.
Lưu ý rằng, bạn có thể mở cửa sổ Command Prompt bằng cách chọn vào
Start | Programs | Microsoft Visual Studio.NET 2003 | Visual Studio.NET Tools |
Visual Studio.NET 2003 Command Prompt.
6. KẾT LUẬN
Chương này chúng ta tìm hiểu tổng quan về Microsoft.NET và cấu trúc
của chương trình C# cùng với cách biên dịch và thực thi class hay project
trong .NET.
- 13 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 2
DỮ LIỆU TRONG C #
- 14 -
NGUYỄN TRẦN MINH KHUÊ
Kiểu dữ liệu của ngôn ngữ C# được chia ra làm hai phần chính là kiểu
giá trị (value type) và kiểu tham chiếu (reference type) và kiểu thứ ba là kiểu con
trỏ (pointers) chỉ tồn tại trong mã không bảo mật (unsafe code).
Value type khác với reference type ở chổ là value type chứa đựng dữ liệu
trực tiếp trong biến trong khi đó reference types chỉ lưu trữ tham chiếu đến dữ
liệu của nó. Với reference type, có thể có hai biến cùng tham chiếu trên cùng
một đối tượng (object), trong khi đó value type thì mỗi biến chỉ có giá trị cho
chính nó không ảnh hưởng đến biến khác.
Kiểu hệ thống của C# là object. Mọi kiểu dữ liệu trong C# đều trực tiếp
hay gián tiếp xuất phát từ kiểu lớp đối tượng.
Các vấn đề chính sẽ được đề cập:
Kiểu dữ liệu Value.
Kiểu dữ liệu Reference.
Kiểu dữ liệu Pointer.
Khái niệm Boxing và UnBoxing.
Chuyển đổi kiểu dữ liệu.
- 15 -
NGUYỄN TRẦN MINH KHUÊ
- 16 -
NGUYỄN TRẦN MINH KHUÊ
sbyte trình bày số nguyên có dấu 8-bit với giá trị trong khoảng –128 và
127.
byte trình bày số nguyên không dấu 8-bit với giá trị trong khoảng 0 và
255.
short trình bày số nguyên có dấu 16-bit với giá trị trong khoảng –32768
và 32767.
ushort trình bày số nguyên không dấu 16-bit với giá trị trong khoảng 0
và 65535.
int trình bày số nguyên có dấu 32-bit với giá trị trong khoảng –
2147483648 và 2147483647.
uint trình bày số nguyên không dấu 32-bit với giá trị trong khoảng 0 và
4294967295.
long trình bày số nguyên có dấu 64-bit với giá trị trong khoảng –
9223372036854775808 và 9223372036854775807.
ulong trình bày số nguyên không dấu 64-bit với giá trị trong khoảng 0
và 18446744073709551615.
char trình bày số nguyên không dấu 16-bit với giá trị trong khoảng 0 và
65535.
7.4.2. Kiểu dấu chấm động
C# hỗ trợ hai kiểu dấu chấm động (floating point) là: float và double dùng
để trình bày dữ liệu 32-bit cho phần chẳn và 64-bit cho phền lẻ:
Float trình bày giá trị trong khoảng 1.5 × 10-45 đến 3.4 × 1038 với độ
chính xác 7 con số.
double trình bày giá trị trong khoảng 5.0 × 10-324 đến 1.7 × 10308 với độ
chính xác 15-16 con số.
7.4.3. Kiểu decimal
Kiểu decimal có kích thước 128-bit phù hợp cho dữ liệu định dạng và tính
toán trong tài chính và tiền tệ. Giá trị trình bày trong khoảng 1.0 × 10 -28 xấp xỉ
đến 7.9 × 1028 với 28-29 con số
7.4.4. Kiểu bool
Kiểu bool dùng để trình bày số luận lý true hay false.
7.4.5. Kiểu enumeration
Kiểu enumeration bao gồm byte, sbyte, short, ushort, int, uint, long hay
ulong. Enumeration được định nghĩa thông qua khai báo enum.
- 17 -
NGUYỄN TRẦN MINH KHUÊ
Không giống như hai kiểu dữ liệu value và reference, kiểu pointer không
chịu sự kiểm soát của garbage collector, bởi vì garbage collector không dùng cho
- 18 -
NGUYỄN TRẦN MINH KHUÊ
kiểu dữ liệu này do chúng không biết dữ liệu mà con trỏ trỏ đến, chính vì vậy
pointer không cho phép tham chiếu đến reference hay một struct có chứa các kiểu
references và kiểu tham chiếu của pointer thuộc loại kiểu không quản lý
(unmanaged-type).
unmanaged-type là kiểu bất kỳ mà nó không thuộc kiểu reference và
không chứa đựng trường reference trong bất kỳ khai báo lồng. Nói cách khác,
unmanaged-type là một trong những kiểu sau:
sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double,
decimal hay bool.
enum bất kỳ.
Pointer bất kỳ.
Kiểu cấu trúc do người dùng định nghĩa (user-defined struct-type) chứa
đựng các trường của unmanaged-type.
Một quy luật trực quan cho sự kết hợp của kiểu pointer và reference là ám
chỉ đến kiểu objects cho phép chứa đựng pointer nhưng pointer không cho phép
chứa đựng kiểu reference. Chẳng hạn, các loại poiter như sau:
byte* Pointer dạng byte
char* Pointer dạng char
int** Pointer dạng con trỏ của int
int*[] Ponter dạng mảng một chiều với các phần tử int
void* Pointer không có kiểu
Không giống như C/C++, khi khai báo nhiều biến pointer trên cùng một
hàng đối với C# có thể như sau:
Ví dụ, khai báo đoạn chương trình với kiểu pointer như sau:
using System;
class pointer
{
static int value = 20;
unsafe static void F(out int* pi1,
ref int* pi2) {
int i = 10;
pi1 = &i;
fixed (int* pj = &value)
{
pi2 = pj;
}
}
unsafe static void Main() {
int* px1;
int i = 10;
int* px2 = &i;
- 19 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class BoxMe
{
static int v=10;
static void Main(string[] args)
{
BoxMe box=new BoxMe();
Console.WriteLine("Boxing & Unboxing");
box.takeObject(v);
object obj=v;
if (obj is int)
{
Console.WriteLine("obj contains an
int");
}
int unBox=(int) box.getObject();
Console.WriteLine("Boxing and
Unboxing:");
Console.WriteLine(unBox.ToString());
Console.ReadLine();
}
}
}
- 20 -
NGUYỄN TRẦN MINH KHUÊ
Bên cạnh hai cách chuyển đổi kiểu dữ liệu trên, boxing, unboxing cho
phép chuyển đổi dữ liệu kiểu object ra kiểu value bất kỳ hay kiểu interface có cài
đặt các kiểu value.
Để kiểm soát quá trình biến đối tượng dữ liệu được thực hiện hoàn hảo
hay không, cấu trúc kiểm soát ngoại lệ trong C# nên được cài đặt.
12. KẾT LUẬN
Trong chương này chúng ta tìm hiểu hai kiểu dữ liệu chính của C# là kiểu
value và reference. Cả hai kiểu dữ liệu này đều được kiểm tra bởi garbage
collector, một kiểu dữ liệu khác không chiệu sự kiểm soát của đối tượng này là
poiter.
Song song với kiểu dữ liệu, hai khái niệm boxing và unboxing cùng với
các chuyển đổi dữ liệu cũng được trình bày trong chương này.
- 21 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 3:
BIẾN
- 22 -
NGUYỄN TRẦN MINH KHUÊ
Biến tượng trưng cho vị trí lưu trữ, mỗi biến có kiểu mà dữ liệu lưu trữ trong
biến.C# là ngôn ngữ kiểu an toàn (type-safe) và trình biên dịch của C# bảo đảm
rằng giá trị lưu trữ trong biến luôn luôn có kiểu thích hợp, giá trị của biến có
thể thay đổi bằng cách sử dụng toán tử ++ và --.
Một biến phải được định nghĩa trước khi sử dụng, giá trị khởi tạo là cần
thiết khi khai báo biến để tránh trường hợp giá trị không tồn tại trong quá trình
thực thi.
using System;
class variable
{
public static int x=0;
int y=10;
static void F(int[] v, int a, ref int b,
out int c) {
int i = 1;
c = a + b++;
Console.WriteLine("a={0},b={1},
c={2}",a,b,c);
for( i=0;i<v.Length;i++)
Console.WriteLine(v[i]);
}
static void Main() {
int[] myarr = new int[5];
variable my = new variable();
for(int j=0;j<myarr.Length;j++)
myarr[j]=j;
Console.WriteLine("Variable");
int aa=20; int bb=10; int cc=0;
Console.WriteLine("x = {0},y={1}",
x,my.y);
F(myarr,aa, ref bb,out cc);
}
}
Trong đó, x là biến static, y là biến instance, v[j] là phần tử mảng thứ j, a
là tham trị, b là tham biến, c là tham số output, và j và i là biến local.
- 23 -
NGUYỄN TRẦN MINH KHUÊ
13.1. Static
Một trường được khai báo với từ khoá static được gọi là biến static. Biến
static có thể truy cập trong toàn bộ class và nó tồn tại trước khi constructor
(static) được thực hiện.
Khi bạn khai báo biến static, bạn có thể truy cập chúng bất kỳ đâu
trong class, giả sử chúng ta khai báo và sử dụng biến static như sau:
using System;
class staticvariable
{
static int x=0;
static void myMethod()
{
x+=10;
Console.WriteLine("x={0}",x);
}
static void Main()
{
myMethod();
x+=10;
Console.WriteLine("x = {0}",x);
}
}
13.2. Instance
Biến không khai báo từ khoá static là biến instance. Biến instance có hai
loại, biến khai báo trong class và struct.
Khai báo biến instance trong class, để truy cập và sử dụng chúng bạn phai
khởi tạo đối tượng, chẳng hạn ví dụ sau:
using System;
class instancevariable
{
int x=10;
static void Main()
{
instancevariable my= new instancevariable();
my.x+=10;
Console.WriteLine("x = {0}",my.x);
// Console.WriteLine("x = {0}",x);
// Lỗi phát sinh khi gọi trực tiếp đến x
//
}
}
- 24 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class Class1
{
static void Main(string[] args)
{
Console.Write("Enter number of array: ");
int ptu= Convert.ToInt16(Console.ReadLine());
int[] myarr = new int[ptu];
int i=0;
for (i = 0;i<ptu;i++)
{
Console.Write("array[" + i.ToString() + "]=");
myarr [i]= Convert.ToInt16(Console.ReadLine());
}
for (i = 0;i<ptu;i++)
{
Console.Write("array[" + i.ToString() + "]=");
Console.WriteLine(myarr [i].ToString());
}
Console.WriteLine("Mang nghich dao la: ");
for (i =ptu-1;i>=0;i--)
{
Console.Write("array[" + i.ToString() + "]=");
Console.WriteLine(myarr [i].ToString());
}
Console.ReadLine();
}
}
using System;
class localvariable
{
static void myarrays(int[] arr) {
int i = 1;
for( i=0;i<arr.Length;i++)
Console.WriteLine(arr[i]);
}
static void Main() {
int[] myarr=new int[5];
for(int j=0;j<myarr.Length;j++)
myarr[j]=j;
Console.WriteLine("Local Variable");
myarrays(myarr);
}
}
- 25 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class variablekeyword
{
static int @int;
static void Main() {
@int+=10;
Console.WriteLine("Value of @int={0}", @int);
}
}
using System;
class defaultvalue
{
static int x;
static void Main() {
Console.WriteLine(
"Default Value of x={0}",x);
Console.WriteLine(
"Default Value of Array");
- 26 -
NGUYỄN TRẦN MINH KHUÊ
Ví dụ, chúng ta khai báo ví dụ với hai mảng myarr và yourarr như sau:
using System;
class array
{
static void Main(string[] args)
{
Console.Write("Please enter number of
array: ");
int ptu=
Convert.ToInt16(Console.ReadLine());
int[] myarr; myarr = new int[ptu];
int i=0;
for (i = 0;i<ptu;i++)
{
Console.Write("array[" + i.ToString()
+ "]=");
myarr [i]=
Convert.ToInt16(Console.ReadLine());
}
Console.WriteLine("Mang cua myarray: ");
for (i = 0;i<ptu;i++)
{
Console.Write("array[" + i.ToString()
- 27 -
NGUYỄN TRẦN MINH KHUÊ
+ "]=");
Console.WriteLine(myarr
[i].ToString());
}
Console.ReadLine();
}
}
Khai báo mảng với số phần tử cho trước và khởi tạo giá trị cho các
phần tử của mảng.
int[] me={1,2,3,4,5};
Ví dụ khai báo mảng với chiều dài cho trước và khởi tạo giá trị cho
từng phần tử như sau:
using System;
class fixedarray
{
static void Main(string[] args)
{
Console.Write("Please enter number of
array: ");
int[] me={1,2,3,4,5};
int i=0;
Console.WriteLine("Mang cua me");
for (i =0;i<me.Length;i++)
{
Console.Write("array[" +
i.ToString() + "]=");
Console.WriteLine(
me [i].ToString());
}
for (i = 0;i<me.Length;i++)
{
Console.Write("array[" +
i.ToString() + "]=");
me[i]=
Convert.ToInt16(Console.ReadLine());
}
Giả sử khai báo mảng myarr, sau đó gán giá trị cho từng phần tử của mảng
myarr, kế đến gán yourarr bằng myarr.
- 28 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class assignarray
{
static void Main(string[] args)
{
Console.Write("Please enter number of
array: ");
int ptu=
Convert.ToInt16(Console.ReadLine());
int[] myarr; myarr = new int[ptu];
int[] yourarr=new int[ptu];
int i=0;
for (i = 0;i<ptu;i++)
{
Console.Write("array[" +
i.ToString() + "]=");
myarr [i]=
Convert.ToInt16(Console.ReadLine());
}
yourarr=myarr;
Console.WriteLine("Mang nghich dao la cua
myarray: ");
for (i =ptu-1;i>=0;i--)
{
Console.Write("array[" + i.ToString()
+ "]=");
Console.WriteLine(
myarr [i].ToString());
}
Console.ReadLine();
}
}
Giả sử, khai báo struct, sau đó gán vào từng field của struct như sau:
public Inventory CreateItem()
{
Inventory temp;
Console.Write("Enter the Items Name : ");
- 29 -
NGUYỄN TRẦN MINH KHUÊ
temp.Item = Console.ReadLine();
using System;
class Obj
{
static int i=10;
static void Main(string[] args)
{
object a=null;
a=i;
Console.WriteLine(a.ToString());
Console.ReadLine();
}
}
using System;
class publicvariable
- 30 -
NGUYỄN TRẦN MINH KHUÊ
{
public static int y=10;
static void Main() {
variable my = new variable();
Console.WriteLine("Variable i="+my.i);
//Console.WriteLine("Variable n="+my.n);
// n mac dinh la protection
Console.WriteLine("y={0}",y);
}
}
class variable
{
public int i=10;
//int n=10;
}
using System;
class protectedvariable
{
static void Main() {
variable my = new variable();
//Console.WriteLine("Variable i="+my.i);
//Console.WriteLine("Variable n="+my.n);
// n mặc định là protection
// nên lỗi sẽ phàt sinh
my.mypro();
}
}
class variable
{
int i=10;
protected int n=10;
public void mypro() {
Console.WriteLine("Variable i="+i);
Console.WriteLine("Variable n="+n);
}
}
18.3. Private
Khi biến khai báo với từ khoá private, biến này có thể truy cập từ đâu
trong class khai báo nó.
Ví dụ bạn khai báo đoạn chương trình sau với biến có tầm vực trong class
khai báo nó.
- 31 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class privatevariable
{
static void Main() {
variable my = new variable();
Console.WriteLine("Variable j="+my.j);
Console.WriteLine(my.getvalue());
//Console.WriteLine("Variable n="+my.n);
// lỗi phát sinh do n là private
}
}
class variable
{
public int j=10;
private int n=10;
public int getvalue()
{
return n;
}
}
- 32 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 4
TOÁN TỬ VÀ BIỂU THỨC
- 33 -
NGUYỄN TRẦN MINH KHUÊ
Giống như các ngôn ngữ lập trình khac, C# có các toán tử đơn, toán tử đôi
và toán tử tam nguyên.
Dựa trên toán tử và toán hạng chúng ta xây dựng một biểu thức so sánh hay
biểu thức gán.
Các vấn đề chính sẽ được đề cập:
Toán tử
Biểu thức trong C#
20. TOÁN TỬ
Trong C# toán tử chia làm 3 loại như sau:
Toán tử đơn: Toán tử đơn sử dụng một toán hạng với ký hiệu tiền tố
hay hậu tố chẳng hạn như –x hay x++.
Toán tử đôi: Toán tử dùng cho hai toán hạng với ký hiệu toán tử ở giữa
như x + y.
Toán tử tam nguyên là toán tử gồm 3 yếu tố. Yếu tố thứ nhất là biểu
thức và hai yêu tố còn lại là hai kết quả đúng và sai tương ứng với biểu thức true
hay false, ví dụ khai báo c? x: y, trong đó c là biểu thức, x là kết quả trả về khi
biểu thức c có giá trị là true, y là kết quả trả về khi biểu thức c có kết quả là false.
20.1. Nhóm toán tử
C# cung cấp các toán tử số học và luận lý cũng như các toán tử khác như
trình bày trong bảng sau:
Số học: + - * / %
Luận lý: & | ^ ! ~ && || true false
Nối chuỗi: +
Tăng giảm: ++ --
Shift: << >>
So sánh: == != < > <= >=
Gán: = += -= *= /= %= &= |= ^= <<= >>=
Thành viên truy cập: .
Chỉ mục: []
Chuyển đổi: Cast()
Tam nguyên: ?:
Nối vào hay loại ra: + -
Tạo mới đối tượng: new
Thông tin kiểu và kích thuớc: sizeof typeof
- 34 -
NGUYỄN TRẦN MINH KHUÊ
object s = 1;
object t = 1;
Console.WriteLine(s != t);
- 35 -
NGUYỄN TRẦN MINH KHUÊ
string a = "hello";
string b = "hello";
Console.WriteLine(a != b);
Console.WriteLine((object)a !=
(object)b);
}
}
21.1.2. So sánh loại dữ liệu
Biểu thức sử dụng toán tử so sánh loại dữ liệu khai báo như sau:
using System;
class Class1
{
}
class Class2
{
}
if (o is Class1)
{
Console.WriteLine ("o is Class1");
a = (Class1)o;
}
else if (o is Class2)
{
Console.WriteLine ("o is Class2");
b = (Class2)o;
}
else
{
Console.WriteLine (
"o is neither Class1 nor Class2.");
}
}
public static void Main()
{
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Test (c1);
Test (c2);
Test ("a string");
}
}
21.2. Biểu thức gán
Biểu thức gán dùng để gán giá trị vào biến khai báo như sau:
using System;
class Test
{
public static void Main()
{
int a = 5;
- 36 -
NGUYỄN TRẦN MINH KHUÊ
a += 6;
Console.WriteLine(a);
string s = "Micro";
s += "soft";
Console.WriteLine(s);
}
}
22. KẾT LUẬN
Trong chương này chúng ta tìm hiểu các loại toán tử và hai loại biểu thức
chính.
- 37 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 5
PHÁT BIỂU ĐIỀU KHIỂN
- 38 -
NGUYỄN TRẦN MINH KHUÊ
C# cung cấp nhiều loại phát biểu như: chọn, lặp, nhảy, kiểm tra, kiểm soát
ngoại lệ, lock và fixed. Trong mỗi phát biểu thường có một hay nhiều khai báo.
Bằng cách sử dụng toán tử và toán hạng chúng ta xây dựng một biểu thức so
sánh kết hợp với phát biểu chọn hay biểu thức gán sử dụng cho phát biểu lặp.
Các vấn đề chính sẽ được đề cập:
Phát biểu chọn
Phát biểu lặp
Phát biểu nhảy
Phát biểu kiểm soát ngoại lệ
Phát biểu checked và unchecked
Phát biểu lock
Phát biểu fixed
if (expression)
statement
if (expression)
{
statement1
statement1
}
Trong đó
expression là biểu thức trả về giá trị bool hay kiểu chứa đựng toán hạn
true hay false.
statement là dòng lệnh sẽ được thực thi khi expression có giá trị là true.
Lưu ý, nếu bên trong phát biểu if có nhiều hơn một phát biểu thì các phát
biểu con đó phải được khai báo trong cặp dấu { và } và statement có thể là một
tập các phát biểu khác.
Ví dụ:
int i=10;
if (x > 10)
{
if (y > 20)
Console.Write("Statement");
}
- 39 -
NGUYỄN TRẦN MINH KHUÊ
if (expression)
statement1
else
statement2
Trong đó
expression là biểu thức trả về giá trị bool hay kiểu chứa đựng toán hạn
true hay false.
statement1 là dòng lệnh sẽ được thực thi khi expression có giá trị là
true.
statement2 là dòng lệnh sẽ được thực thi khi expression có giá trị là
false.
Ví dụ:
int i=10;
if (x > 10)
{
if (y > 20)
Console.Write("Statement1");
else
Console.Write("Statement2");
}
23.3. Phát biểu switch và case
Phát biểu switch là phát biểu điều khiển nhiều chọn lựa bằng cách truyển
điều khiển đến phát biểu case bên trong.
switch (expression)
{
case constant-expression:
statement
jump-statement
[default:
statement
jump-statement]
}
Trong đó
expression là biểu thức số nguyên hay là chuỗi.
statement là dòng lệnh sẽ được thực thi khi expression chuyển đến case
hay default.
jump-statement là phát biểu nhảy ra khỏi phát biểu switch.
constant-expression nhảy đến case với giá trị chỉ định có khai báo trong
phát biểu switch.
- 40 -
NGUYỄN TRẦN MINH KHUÊ
Lưu ý, nếu bên trong phát biểu case nếu có nhiều hơn một phát biểu thì
không cho phép khai báo trong cặp dấu { và }.
Ví dụ:
using System;
class SwitchTest
{
public static void Main()
{
Console.WriteLine("Sizes: 1=Small 2=Medium 3=Large");
Console.Write("Enter your selection: ");
string s = Console.ReadLine();
int n = int.Parse(s);
int cost = 0;
switch(n)
{
case 1:
cost += 25;
break;
case 2:
cost += 25;
goto case 1;
case 3:
cost += 50;
goto case 1;
default:
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break;
}
if (cost != 0)
Console.WriteLine("Insert {0} cents.", cost);
Console.WriteLine("Thank you.");
}
}
24. PHÁT BIỂU LẶP
Phát biểu vòng lặp trong C# bao gồm do, for, foreach, in, while. Bằng
cách sử dụng phát biểu vòng lặp bạn có thể thực thi một tập lệnh nhiều lần cho
đến khi kết thúc hay gặp phát biểu thoát ra khỏi vòng lặp.
24.1. Vòng lặp do
Vòng lặp do thực thi một hay nhiều phát biểu bên trong cho đến khi biểu
thức có giá trị là false với cú pháp như sau:
do
statement
while (expression);
Trong đó:
expression: expression dùng để kiểm tra điều kiện kết thúc vòng lặp do.
statement: Một hay nhiều tập lệnh bên trong.
Ví dụ:
using System;
public class TestDoWhile
{
- 41 -
NGUYỄN TRẦN MINH KHUÊ
do
{
x = y++;
Console.WriteLine(x);
}
Trong đó:
initializers: initializers là giá trị bắt đầu vòng lặp for.
iterators: iterators là giá trị tăng hay giảm trong vòng lặp for.
expression: expression dùng để kiểm tra điều kiện trả về giá trị bool kết
thúc vòng lặp for.
statement: Một hay nhiều tập lệnh bên trong.
Ví dụ:
using System;
public class ForLoopTest
{
public static void Main()
{
for (int i = 1; i <= 5; i++)
Console.WriteLine(i);
}
}
Trong đó:
- 42 -
NGUYỄN TRẦN MINH KHUÊ
type: type là kiểu dữ liệu nhận dạng tương thích với kiểu dữ liệu của
phần tử trong mảng hay tập đối tượng.
identifier: Biến có kiểu kahi báo type sẽ hiện thực giá trị của phần tử
trong expression.
expression: expression là tập đối tượng hay mảng.
statement: Một hay nhiều tập lệnh bên trong.
Ví dụ sử dụng foreach với mảng dữ liệu:
using System;
class foreacharray
{
public static void Main()
{
int odd = 0, even = 0;
int[] arr = new int [] {0,1,2,5,7,8,11};
while (expression)
- 43 -
NGUYỄN TRẦN MINH KHUÊ
statement
Trong đó:
expression: expression dùng để kiểm tra điều kiện kết thúc vòng lặp
while.
statement: Một hay nhiều tập lệnh bên trong.
Ví dụ:
using System;
class WhileTest
{
public static void Main()
{
int n = 1;
while (n < 6)
{
Console.WriteLine("Current value of n is {0}", n);
n++;
}
}
}
break;
- 44 -
NGUYỄN TRẦN MINH KHUÊ
switch(n)
{
case 1:
Console.WriteLine("value is {0}", 1);
break;
case 2:
Console.WriteLine("value is {0}", 2);
break;
case 3:
Console.WriteLine("value is {0}", 3);
break;
default:
Console.WriteLine("Sorry, invalid selection.");
break;
}
}
}
continue;
Trong ví dụ trên, biến i duyệt từ 1 đến 10, nếu biến i có giá trị còn nhỏ
hơn 9 thì những phát biểu khai báo giữa phát biểu continue và phát biểu kết thúc
của vòng for sẽ được bỏ qua.
25.3. Phát biểu default
Phát biểu default được khai báo trong phát biểu switch khi biểu thức so
sánh không thuộc một trong những giá trị khai báo trong phát biểu case.
Ví dụ chúng ta có khai báo default trong phát biểu switch như sau:
using System;
class SwitchTest
{
public static void Main()
{
- 45 -
NGUYỄN TRẦN MINH KHUÊ
goto identifier;
goto case constant-expression;
goto default;
Trong đó:
identifier: là nhãn (label).
constant-expression: là nhãn của phát biểu switch.
Ví dụ sử dụng phát biểu goto như sau:
using System;
public class GotoLabel
{
public static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] myArray = new string[x,y];
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
myArray[i,j] = (++count).ToString();
Console.Write("Enter the number to search for: ");
string myNumber = Console.ReadLine();
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
if (myArray[i,j].Equals(myNumber))
goto Found;
- 46 -
NGUYỄN TRẦN MINH KHUÊ
Finish:
Console.WriteLine("End of search.");
}
}
return [expression];
checked block
Trong đó
block: Khối phát biểu chứa đựng các biểu thức cần kiểm tra.
expression: Biếu thức được kiểm tra được đặt trong cặp dấu ().
Ví dụ sử dụng check như toán tử:
- 47 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class OverFlowTest
{
static short x = 32767;
// Giá trị lớn nhất của short
static short y = 32767;
try
{
z = checked((short)(x + y));
}
catch (System.OverflowException e)
{
System.Console.WriteLine(e.ToString());
}
return z;
// Lỗi sẽ phu ra OverflowException
}
class TestClass
{
const int x = 2147483647;
const int y = 2;
- 48 -
NGUYỄN TRẦN MINH KHUÊ
unchecked block
Trong đó
block: Khối phát biểu chứa đựng các biểu thức không cần kiểm tra.
expression: Biếu thức không kiểm tra được đặt trong cặp dấu ( ).
Ví dụ sử dụng uncheck như phát biểu
using System;
class TestClass
{
const int x = 2147483647;
const int y = 2;
class OverFlowTest
{
static short x = 32767;
static short y = 32767;
- 49 -
NGUYỄN TRẦN MINH KHUÊ
lock(expression) statement_block
Trong đó
expression: Chỉ định đối tượng mà bạn muốn khoá, expression phải là
kiểu reference.
statement_block: Các phát biểu cần khoá.
Ví dụ:
using System;
using System.Threading;
class Account
{
int balance;
- 50 -
NGUYỄN TRẦN MINH KHUÊ
class Test
{
public static void Main()
{
Thread[] threads = new Thread[10];
Account acc = new Account (1000);
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new
ThreadStart(acc.DoTransactions));
threads[i] = t;
}
for (int i = 0; i < 10; i++)
{
threads[i].Start();
}
}
}
Trong đó
type: Kiểu không quản lý hay void.
ptr: Tên con trỏ.
rxpr: Biểu thức ct đổi sang kiểu con trỏ.
statement: Phát biểu hay một khối phát biểu.
Ví dụ
using System;
class Point {
public int x, y;
}
class FixedTest
{
// phương thức unsafe dùng đến pointer với int
unsafe static void SquarePtrParam (int* p)
{
*p *= *p;
}
- 51 -
NGUYỄN TRẦN MINH KHUÊ
- 52 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 6
PHƯƠNG THỨC
- 53 -
NGUYỄN TRẦN MINH KHUÊ
C# cung cấp nhiều loại phát biểu như: chọn, lặp, nhảy, kiểm tra, kiểm soát
ngoại lệ, lock và fixed. Trong mỗi phát biểu thường có một hay nhiều khai báo.
Bằng cách sử dụng toán tử và toán hạng chúng ta xây dựng một biểu thức so
sánh kết hợp với phát biểu chọn hay biểu thức gán sử dụng cho phát biểu lặp.
Các vấn đề chính sẽ được đề cập:
Phương thức Main
Phương thức void và phương thức trả về
Tầm vực của phương thức
Tham số
Phương thức Main có thể là void nhưng cũng có thể là một phương thức
trả về có hoặc không các tham số. Tham số có thể được truyền vào có dạng mảng
mỗi phần tử là một từ khi chương trình được thực thi.
Nếu trong chương trình có sử dụng đến mảng này thì người sử dụng cần
cung cấp giá trị dạng chuỗi, mỗi từ là giá trị của mỗi phần tử.
using System;
class voidmain
{
static void Main(string[] args)
{
foreach(string s in args)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
Sau khi biên dịch class trên, để chạy tập tin exe bạn cung cấp tham số cho
phương thức Main như sau:
D:\CSharp\csc voidmain.cs
D:\CSharp\voidmain “Hello World”
Nếu thực thi chương trình trong Visual Studio.Net, bạn khai báo tham số
này trong phần ProjectName Properties | Debugging | Command line Arguments
như hình 6-1.
- 54 -
NGUYỄN TRẦN MINH KHUÊ
using System;
class Class1
{
static void Main(string[] args)
{
Console.WriteLine("void method");
tong();
Console.WriteLine();
}
/*Khai báo phương thức void*/
static void tong()
{
- 55 -
NGUYỄN TRẦN MINH KHUÊ
Console.ReadLine());
Console.Write("Result: ");
Console.WriteLine(ptu1+ptu2);
}
}
using System;
class Class1
{
static void Main(string[] args)
{
Console.Write("Enter the 1st number: ");
int ptu1=Convert.ToInt16(
Console.ReadLine());
Console.Write("Enter the 2rd number: ");
int ptu2=Convert.ToInt16(
Console.ReadLine());
Console.Write("Result: "+
tong(ptu1, ptu2));
Console.WriteLine();
}
Lưu ý:
Không nên khai báo return trước các khai báo còn lại trong phương thức.
Phát biểu return được bỏ qua nếu khai báo chúng trong phương thức void.
32. TẦM VỰC CỦA PHƯƠNG THỨC<<KHÔNG PHẢI BIẾN NHƯ
TRÊN>
Tương tự như biến, tầm vực của phương thức được chia làm 3 loại như:
public, protected và private.
32.1. Public class này <<có thể gọi p/t public trong class kia >>
Cho phép truy cập đến phương thức mọi nơi, ví dụ chúng ta có hai class
trong tập tin .cs, phương thức khai báo với tầm vực là public có thể gọi trong
class khác như sau:
using System;
class publicroutine
{
public static int y=10;
static void Main() {
routine my = new routine();
Console.WriteLine("Routine tong ");
Console.WriteLine(my.tong(y,y+1));
Console.ReadLine();
}
}
Class routine
- 56 -
NGUYỄN TRẦN MINH KHUÊ
{
public int tong(int i,int j)
{
return i+j;
}
}
32.2. Protected
Cho phép truy cập đến phương thức trong phạm vi class khai báo nó hoặc
từ các class có khai báo kế thừa từ class này, ví dụ chúng ta có hai class trong tập
tin .cs, phương thức khai báo với tầm vực là protected có thể gọi trong class khác
như sau:
using System;
class protectedroutine
{
public static int y=10;
static void Main() {
routine my = new routine();
Console.WriteLine("Routine tong ");
Console.WriteLine(my.result(y,y+1));
//Console.WriteLine(my.tong(y,y+1)); //
Console.ReadLine();
}
}
Class routine
{
public int result(int i,int j)
{
return tong(i,j+10);
}
protected int tong(int i,int j)
{
return i+j;
}
}
Trong ví dụ trên, không cho phép gọi phương thức tong trong class
protectedroutine mà chỉ cho phép gọi phương thức này trong class routine.
32.3. Private
Từ khoá private cho phép truy cập đến phương thức trong phạm vi class
khai báo nó, ví dụ chúng ta có hai class trong tập tin .cs, phương thức khai báo
với tầm vực là private có thể gọi trong class khác như sau:
using System;
class privatedroutine
{
public static int y=10;
static void Main() {
routine my = new routine();
Console.WriteLine("Routine tong ");
Console.WriteLine(my.result(y,y+1));
//Console.WriteLine(my.tong(y,y+1));
Console.ReadLine();
}
}
Class routine
{
public int result(int i,int j)
{
return tong(i,j+10);
- 57 -
NGUYỄN TRẦN MINH KHUÊ
}
private int tong(int i,int j)
{
return i+j;
}
}
Nếu bạn không khai báo một trong ba từ khoá trên cho phương thức thì
mặc định là private.
33. THAM SỐ
Mỗi phương thức trong C# có thể có tham số truyền vào, kiểu dữ liệu của
tham số là mọi kiểu dữ liệu hỗ trợ trong C#. Có hai loại tham số chính trong
phương thức của C#.
33.1. Tham trị
Nếu tham số khai báo trong phương thức không có từ khoá ref hay out thì
tham số sẽ có giá trị trước khi truyền vào phương thức và ra khỏi phương thức
không thay đổi cho dù bên trong phương thức giá trị có thể thay đổi.
Ví dụ, chúng ta khai báo phương thức có tên paravalue nhận 2 tham số,
tham số thứ nhất và thứ hai là hai số nguyên theo hình thức tham trị, giá trị sẽ
được thay đổi trong phương thức nhưng kết quả in ra trước và sau khi truyền vào
phương thức là giống sau:
using System;
class valueparameter
{
static void Main(string[] args)
{
Console.WriteLine("Pass parameter");
int i=10;int j=5;
Console.WriteLine("i={0}, j={1}: ",i,j); Console.WriteLine("Result:
");
valuepara(i,j);
Console.WriteLine("i={0}, j={1}: ",i,j);
Console.WriteLine();
}
- 58 -
NGUYỄN TRẦN MINH KHUÊ
Trong C# để sử dụng tham biến, bạn có thể sử dụng một trong hai từ khoá
ref hay out.
33.2.1. Tham số với từ khoá ref
Khi sử dụng tham biến với từ khoá ref thì tham số truyền vào phương thức
phải khai báo từ khoá ref. Tham số này phải khởi tạo trước khi truyền vào
phương thức, đó là sự khác biệt với tham biến với từ khoá out, giá trị không cần
khởi tạo trước.
Một thuộc tính không phải là biến sẽ không thể truyền vào phương thức
dưới dạng tham biến với từ khoá ref. Chẳng hạn, chúng ta khai báo phương thức
refpara nhận hai tham số, tham số thứ nhất là số nguyên dưới dạng ref và tham số
thứ hai là số nguyên dưới dạng tham trị như sau:
using System;
class refparameter
{
static void Main(string[] args)
{
Console.WriteLine("Pass parameter");
/*Khởi tạo giá trị cho i*/
int i=10;int j=5;
Console.WriteLine("i={0}, j={1}
",i,j);
Console.WriteLine("Result: ");
/*Truyền i với tham số ref*/
refpara(ref i,j);
Console.WriteLine("i={0}, j={1}
",i,j);
Console.WriteLine();
}
Kết quả in ra i có thay đổi thành 11 còn j thì vẫn giá trị trước khi vào
phương thức:
Pass parameter
i=10, j=5
Result:
changed i=11, j=6
i=11, j=5
- 59 -
NGUYỄN TRẦN MINH KHUÊ
Một biến truyền vàp phương thức với từ khoá out không cấn khởi tạo. Tuy
nhiên, tham số này phải được gán giá trị trong phương thức trước khi trả về.
Một thuộc tính không phải là biến sẽ không thể truyền vào phương thức
dưới dạng tham biến với từ khoá out.
Chẳng hạn, chúng ta khai báo phương thức para nhận hai tham số, tham số
thứ nhất là số nguyên dưới dạng out và tham số thứ hai là số nguyên dưới dạng
ref như sau:
using System;
class outparameter
{
static void Main(string[] args)
{
Console.WriteLine("Pass parameter");
int i=0;int j=10;
Console.WriteLine("i={0}, j={1}
",i,j);
Console.WriteLine("Result: ");
para(out i,ref j);
Console.WriteLine("i={0}, j={1}
",i,j);
Console.WriteLine();
}
Kết quả in ra i có thay đổi thành 11 và j thì có giá trị thay đổi là 6:
Pass parameter
i=0, j=5
Result:
changed i=11, j=6
i=10, j=6
using System;
public class myparams
{
- 60 -
NGUYỄN TRẦN MINH KHUÊ
Console.WriteLine(list[i]);
Console.WriteLine();
}
1
2
3
1
a
test
10
11
12
- 61 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 7
OOP TRONG C#
- 62 -
NGUYỄN TRẦN MINH KHUÊ
C# là ngôn ngữ lập trình hướng đối tượng, chúng ta có thể cài đặt OOP
trong C# với: Constructor, Destructor, Garbage Collector, Overloading,
Inheritance, Overriding, Polymorphism và Interfaces.
Các vấn đề chính sẽ được đề cập:
Constructors
Định nghĩa Overloading
Cài đặt Inheritance và Sealed class
Cài đặt Overriding
Cài đặt Polymorphism
Abstract base classes
Khai báo Interfaces
Định nghĩa Interface
35. CONSTRUCTORS
35.1. Khai báo Constructor
Constructor là một phương thức đặc biệt cùng tên với tên của class được
gọi bất kỳ lúc nào sau kh class được tạo ra. Thuờng sử dụng Constructore để khởi
tạo giá trị. Chẳng hạn, chúng ta có class tên là clsA thì tên của Constructor cũng
có tên clsA như khai báo sau:
using System;
class testcon
{
public int j;
public int i;
/*Constructor*/
public testcon()
{
i=10;j=15;
}
}
/*Class chính*/
class calltestcon
{
static void Main()
{
testcon a=new testcon();
Console.WriteLine("i={0},
j={1}",a.i,a.j);
Console.ReadLine();
}
}
Như trình bày ở trên Constructor là phương thức đặc biệt, chính vì vậy nó
cũng có thể có tham số, bạn có thể thay đổi giá trị của thuộc tính trong
- 63 -
NGUYỄN TRẦN MINH KHUÊ
constructor, chẳng hạn khi khởi tạo class, bằng cách tuyền giá trị vào tham số
tương ứng của constructor như khai báo sau:
using System;
class constructorparameter
{
public int j=10;
public int i;
public constructorparameter()
{
i=10;
}
public constructorparameter(int d)
{
j+=d;
}
}
class calltestcon
{
static void Main()
{
Console.WriteLine("Constructor
without parameter");
constructorparameter cplus= new
constructorparameter();
Console.WriteLine("i={0},
j={1}",cplus.i,cplus.j);
Console.WriteLine("Constructor with
parameter");
constructorparameter csharp=new
constructorparameter(20);
Console.WriteLine("i={0},
j={1}",csharp.i,csharp.j);
Console.ReadLine();
}
}
Trong C# không có destructor, nhưng chúng cho phép khai báo cấu trúc
này tương tự như trong ngôn ngữ lập trình C++. Phương thức destructor sẽ được
gọi khi một đối tượng bị huỷ bỏ. Tuy nhiên, trong C# sử dụng khai niệm Garbage
collector thay vì sử dụng cấu trúc destructor.
Để khai báo destructor trong C#, bạn khai báo tên trùng với tên của class
nhưng có ký tự ~ đi trước.
using System;
class destructorparameter
{
public int j=10;
public int i;
public destructorparameter ()
{
i=10;j++;
}
~ destructorparameter (){
- 64 -
NGUYỄN TRẦN MINH KHUÊ
}
class calltestcon
{
static void Main()
{
destructorparameter cplus= new
destructorparameter ();
Console.WriteLine("i={0},
j={1}",cplus.i,cplus.j);
Console.ReadLine();
}
}
Garbage Collector có trách nhiệm giải phóng bộ nhớ bị chiếm bởi các đối
tượng không còng sử dụng hay tham chiếu.
Khi một đối tượng bị huỷ, trình thực thi sẽ liệt kê đối tượng này vào danh
sách yêu cầu bị huỷ. Garbage Collector kiểm tra xem đối tượng này còn sử dụng
nữa hay không, nếu tên của đối tượng này không xuất hiện trong danh sách cần
xoá thì chúng sẽ được đánh dấu sẵng sàng. Sau khi đã đánh dấu tất các đối tượng
cần xoá, chúng sẽ thực hiện tiếp tác vụ sẽ xoá tất cả các đối tượng đói khỏi danh
sách này và tiếp tục thực hiện cho lần kế tiếp.
36. ĐỊNH NGHĨA OVERLOADING
Những phương thức khai báo trong C# có thể cùng tên (overload) theo hai
cách sau:
Khác số lượng tham số truyền vào phương thức
Chỉ định kiểu dữ liệu của tham số khác nhau
Overload không hỗ trợ phương thức trả về giá trị trong ngôn ngữ lập trình
C#. Bạn có thể xem constructor như một phương thức overload.
36.1. Overloading khác số lượng tham số
C# cho phép khai báo phương thức cùng tên trong class với số lượng tham
số khác nhau:
using System;
class overload
{
public static int op1=0;
public static int op2=0;
public static int total=0;
/* phương thức “tinh” có 2 tham số */
public static void tinh(int a, int b)
{
total=a+b;
- 65 -
NGUYỄN TRẦN MINH KHUÊ
}
/* phương thức “tinh” có 3 tham số */
public static void tinh(int a, int b,string symbol)
{
switch(symbol)
{
case "+":
total=a+b;break;
case "-":
total=a-b;break;
case "*":
total=a*b;break;
case "/":
total=a/b;break;
case "%":
total=a%b;break;
}
}
}
Trong trường hợp tham số truyền vào phương thức cùng nhau thì phải
khác nhau về kiểu dữ liệu, ví dụ chúng ta khai báo:
using System;
class overload
{
public static int op1=100;
public static long op2=15000000000;
public static long total=0;
/*Khai báo phương thức “tinh” cùng tên*/
public static void tinh(int a, int b)
{
total=a+b+100;
}
/*Khai báo phương thức “tinh” cùng tên và khác kiểu dữ liệu của tham số*/
public static void tinh(int a, long b)
{
total=a+b;
- 66 -
NGUYỄN TRẦN MINH KHUÊ
Ngôn ngữ lập trình hướng đối tượng cho phép chúng ta khai báo và sử
dụng lại class nhằm sử dụng lại những tài nguyên đã có. Khái niệm sử dụng lại
class đã khai báo trước đó được biến đến là tính kế thừa (Inheritance).
37.1. Kế thừa
C# hỗ trợ đa kế thừa cho phép một class có thể kế thừa từ nhiều class
khác.
using System;
/*Khai báo class để cho phép class khác kế thừa*/
class Tinhtoan
{
public long Tinh(int a, int b,string symbol)
{
long total=0;
switch(symbol)
{
case "+":
total=a+b;break;
case "-":
total=a-b;break;
case "*":
total=a*b;break;
case "/":
total=a/b;break;
case "%":
total=a%b;break;
}
return total;
}
}
/*Khai báo class để kế thừa class khác*/
class inheritance:Tinhtoan
{
static void Main()
{
inheritance t =new inheritance();
- 67 -
NGUYỄN TRẦN MINH KHUÊ
Trong trường hợp khai báo class không cho phép class khác kê thừa bạn
sử dụng từ khoá sealed.
using System;
/*Khai báo class không cho phép kế thừa*/
sealed class Tinhtoan
{
public long Tinh(int a, int b,string symbol)
{
long total=0;
switch(symbol)
{
case "+":
total=a+b;break;
case "-":
total=a-b;break;
case "*":
total=a*b;break;
case "/":
total=a/b;break;
case "%":
total=a%b;break;
}
return total;
}
}
/*nếu khai báo kế thừa sẽ phát sinh lôi khi biên dịch*/
class clssealed//:Tinhtoan
{
static void Main()
{
Tinhtoan t =new Tinhtoan();
//clssealed t =new clssealed();
/*Khong the ke thua, cho nên khai báo để khởi
tạo đối tượng Tinhtoan thay vì clssealed*/
Console.WriteLine("Nhap so luong ban ");
Console.WriteLine("------------------");
Console.Write("So luong= ");
int a=Convert.ToInt16(Console.ReadLine());
Console.Write("Don gia= ");
int b=Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Khong the ke thua");
Console.WriteLine("------------------");
long kq=t.Tinh(a,b,"*");
Console.WriteLine("Ket qua: " +
kq.ToString());
Console.ReadLine();
- 68 -
NGUYỄN TRẦN MINH KHUÊ
}
}
Chúng ta vừa tham khảo cách cài đặt inheritance trong C#, trong trường
hợp có hai phương thức khác báo trong hai class có kế thừa nhau cùng tên thì
phải sử dụng từ khoá new để cho phép overriding.
using System;
/*Khai báo phương thức cho phép kế thừa*/
class overriding
{
public long tinh(int a, int b,string symbol)
{
long total =0;
switch(symbol)
{
case "+":
total=a+b;break;
case "-":
total=a-b;break;
case "*":
total=a*b;break;
case "/":
total=a/b;break;
case "%":
total=a%b;break;
}
return total;
}
}
class testoverriding:overriding
{
new long tinh(int a, int b,string symbol)
{
/*cong them 10 de biet su khac biet
voi phuong thuc tren*/
return a+b+10;
}
}
}
- 69 -
NGUYỄN TRẦN MINH KHUÊ
Sau khi khai báo kề thừa class overriding, thay vì sử dụng phương thức
Tinh của class này bạn có thể khai báo phương thức cùng tên sau đó sử dụng từ
khoá để overriding phương thức Tinh trong class kế thừa.
39. CÀI ĐẶT POLYMORPHISM
Polymorphism bao gồm phương thức ảo (Virtual Method) cho phép chúng
ta cài đặt phương thức xuất phát từ lớp khác trong quá trình thực thi.
Khi khai báo các class khác có kế thừa từ class có khai báo Virtual
Method phải sử dụng từ khoá override, khi đó đối tượng khởi tạo sẽ trở thành
một mảng bao gồm các class thành viên như sau:
using System;
public class Salary
{
public virtual int Income(int SalaryContract,
int Allowance,int Rate)
{ return (SalaryContract + Allowance)*Rate;
}
}
public class Commission:Salary
{
public override int Income(int USD,int VND,
int Rate)
{
return USD*Rate + VND;
}
}
public class OverTime:Salary
{
public override int Income(int USD,int VND,
int Rate)
{
return USD*Rate + VND;
}
}
public class GrossIncome
{
static int Rate=15000;
/*Exchange Rate base on USD*/
static void Main()
{
Salary[] inc=new Salary[3];
inc[0]=new Salary();
inc[1]=new Commission();
inc[2]=new OverTime();
int sal =inc[0].Income(100,50,Rate);
int com =inc[1].Income(0,100000,Rate);
int ot=inc[2].Income(0,100000,Rate);
Console.WriteLine();
Console.WriteLine("Tien luong");
Console.WriteLine("-------------------");
Console.Write("Quy ra tien dong:");
Console.WriteLine(sal+com+ot);
Console.WriteLine("-------------------"); Console.WriteLine("Salary:{0}\n
Commissoin:{1}\nOT:{2}",sal,com,ot);
Console.Write("Press any key to continue");
Console.ReadLine();
}
- 70 -
NGUYỄN TRẦN MINH KHUÊ
C# cho phép bạn cài đặt một lớp trừ tượng cơ sở với từ khoá Abstract, các
phương thức khai báo trong lớp này có thể có phần khai báo bên trong hoặc
không.
Trong trường hợp những phương thức không có phần thân chương trình
thì bạn có thể khai báo chúng trong một class khác sau đó khai báo kế thừa từ
class này.
using System;
abstract class Tinhtoan
{
public abstract long Tinh(int a, int b);
}
class TestAbstract
{
static void Main(string[] args)
{
Thuvien tv= new Thuvien();
Tinhtoan tt=tv;
int i=1000; int j=2000;
/*Gọi phương thức Tinh trên class
Tinhtoan*/
Console.WriteLine("Ket qua: " +
tt.Tinh(i,j));
Console.ReadLine();
}
}
Chúng ta vừa tham khảo cách cài đặt một class dạng lớp trừu tượng,
interface là một class trừu tượng nó chứa đựng các phương thức trừu tượng và
không trừu tượng.
41.1. Định nghĩa Interface
Đối tượng của interface không bao giờ được tạo ra, cho phép bạn khai báo
tên phương thức trong class này nhưng phần thân của phương thức sẽ được khai
báo trong class khác.
Chẳng hạn, bạn khai báo tên phương thức trong class clsA như sau:
- 71 -
NGUYỄN TRẦN MINH KHUÊ
using System;
public interface Tinhtoan
{
long Tinh(int a, int b);
}
/*Khai báo phần thân của phương thức*/
public class Tinhtoans: Tinhtoan
{
public long Tinh(int a, int b)
{
a++;b++;
return (a+b);
}
}
class TestInterface
{
static void Main(string[] args)
{
Tinhtoans tt= new Tinhtoans();
int i=1000; int j=2000;
Console.WriteLine("Ket qua: " +
tt.Tinh(i,j));
Console.ReadLine();
}
}
Trong C# cho phép chúng ta cài đặt đa interface, bằng cách này bạn có thể
khai báo tên của phương thức trên hai interface khác nhau nhưng phần thân của
chúng được khai báo trong cùng một class.
using System;
/*Khai báo interface thứ nhất*/
public interface Tinhtoan
{
long Tinh(int a, int b);
}
/*Khai báo interface thứ hai*/
public interface Inan
{
void Ketqua(int a, int b);
}
/*Khai báo phần thân của các phương thức trong
interface thứ nhất và thứ hai*/
public class Tinhtoans: Tinhtoan,Inan
{
public long Tinh(int a, int b)
{
a++;b++;
return (a+b);
}
public void Ketqua(int a, int b)
{
Console.WriteLine("a=" +a);
Console.WriteLine("a=" +b);
}
}
class TestInterface
{
static void Main(string[] args)
{
- 72 -
NGUYỄN TRẦN MINH KHUÊ
Trong trường hợp hai phương thức khai báo trong hai interface cùng tên
nhau, bạn khai báo phần thân của mỗi phương thức trong class kế thừa bằng cách
chỉ định tên của interface cho mỗi phương thức.
using System;
/*Khai báo phương thức “tinh” trong interface
thứ nhất*/
public interface Tinhtoan
{
long Tinh(int a, int b);
}
/*Khai báo phương thức “tinh” trong interface
thứ hai*/
public interface Calculate
{
long Tinh(int a, int b);
}
/*Cai đặt 2 phương thức “tinh” trong class
thứ nhất*/
public class Tinhtoans: Tinhtoan, Calculate
{
long Tinhtoan.Tinh(int a, int b)
{
a++;b++;
return (a+b);
}
long Calculate.Tinh(int a, int b)
{
return (a+b);
}
}
class TestInterface
{
static void Main(string[] args)
{
Tinhtoans tt= new Tinhtoans();
int i=1000; int j=2000;
Console.WriteLine("Ket qua: " +
tt.Tinh(i,j));
Console.ReadLine();
}
}
Trong chương này, chúng ta tìm hiểu cài đặt OOP trong C# với
Constructor, Destructor, Garbage Collector, Overloading, Inheritance,
Overriding, Polymorphism và Interfaces.
- 73 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 8
KIỂM SOÁT NGOẠI LỆ
- 74 -
NGUYỄN TRẦN MINH KHUÊ
C# cung cấp cấu trúc điều khiển try-cacth-finally cho phép chúng ta kiểm
soát lỗi trong quá trình thực thi chương trình. Đối tượng Exception cung cấp
toàn bộ thông tin của lỗi xảy ra.
Các vấn đề chính sẽ được đề cập:
Tìm hiểu lớp kiểm soát lỗi (Exceptions Class)
Khai báo kiểm soát lỗi (Exceptions Handle)
Lỗi do người sử dụng định nghĩa
Exception
IOException
SystemException
OutOfMemoryException
OverflowException
FormatException
….....
Tuỳ thuộc vào việc xác định lỗi phát sinh trong khi thực thi chương trình
thuộc loại nào thì bạn sẽ sử dụng đối tượng đó cho phù hợp.
Khi sử dụng đúng đối tượng Exception cho lỗi phát sinh, đối tượng sẽ
cung cấp thông tin chi tiết của lỗi xảy ra thay vì sử dụng trường hợp tổng quát.
Tuy nhiên, trong trường hợp không xác định được lỗi sẽ phát sinh thuộc
loại đối tượng chỉ định, bạn sử dụng đối tượng Exception để nắm các thông tin
chính do lỗi phun ra.
- 75 -
NGUYỄN TRẦN MINH KHUÊ
throw [expression];
Trong đó
expression là đối tượng nó sẽ được bỏ qua khi noại lệ hiện hành nằm
trong mệnh đề catch.
Ví dụ:
using System;
public class ThrowTest
{
public static void Main()
{
string s = null;
if (s == null)
{
throw(new ArgumentNullException());
}
try try-block
catch (exception-declaration-1) catch-block-1
catch (exception-declaration-2) catch-block-2
...
try try-block catch catch-block
Thông thường khai báo mệnh đề try ứng với một mệnh đề catch như sau:
using System;
class trycatch
{
public static void Main()
{
trycatch x = new trycatch ();
try
{
string s = null;
- 76 -
NGUYỄN TRẦN MINH KHUÊ
x.MyFn(s);
}
catch (Exception e)
{
Console.WriteLine("{0}
Exception caught.", e);
}
}
Nếu đoạn chương trình trong khai báo try có thể có nhiều loại exception
xảy ra, chúng ta có thể sử dụng nhiều mệnh đề catch như sau:
using System;
class MyClass
{
public static void Main()
{
MyClass x = new MyClass();
try
{
string s = null;
x.MyFn(s);
}
Lưu ý: Mệnh đề catch thứ hai sẽ được sử dụng khi chương trình có lỗi.
Tuy nhiên, chúng ta có thể thay đổi mệnh đề catch thứ hai bằng cách khai báo
như sau:
using System;
class MyClass
{
public static void Main()
- 77 -
NGUYỄN TRẦN MINH KHUÊ
{
MyClass x = new MyClass();
try
{
string s = null;
x.MyFn(s);
}
catch (ArgumentNullException e)
{
Console.WriteLine("{0}
First exception caught.", e);
}
}
Trong đó
try-block: Chứa đựng các khai báo muốn kiểm soát ngoại lệ.
finally-block: Chứa đựng các khai báo để xoá tài nguyên sử dụng
trong try.
Ví dụ:
using System;
public class TestTryFinally
{
public static void Main()
{
int i = 123;
string s = "Some string";
object o = s;
try
{
/* Invalid conversion;
o contains a string not an int*/
i = (int) o;
}
finally
{
Console.Write("i = {0}", i);
}
}
}
- 78 -
NGUYỄN TRẦN MINH KHUÊ
try
try-block
catch
catch-block
finally
finally-block
Trong đó
try-block: Chứa đựng các khai báo cần kiểm soát ngoại lệ.
catch-block: Chứa đựng các khai báo kiểm soát ngoại lệ.
finally-block: Chứa đựng các khai báo để xoá tài nguyên sử dụng
trong try.
Ví dụ:
using System;
public class trycatchfinally
{
public static void Main ()
{
try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch(NullReferenceException e)
{
Console.WriteLine("{0}
Caught exception #1.", e);
}
catch
{
Console.WriteLine("Caught
exception #2.");
}
finally
{
Console.WriteLine("Executing finally
block.");
}
}
}
Dựa vào lớp Exception, chúng ta có thể phun ra thông báo tuỳ thích mỗi
khi phát sinh lỗi. Chẳng hạn, bạn khai báo đoạn chương trình đọc tập tin trên đĩa,
- 79 -
NGUYỄN TRẦN MINH KHUÊ
nếu tập tin không tồn tại thay vì xuất câu thông báo thì bạn phun ra chuỗi như
thuộc tính Message của đối tượng Exception.
using System;
using System.IO;
class Class1
{
static void Main(string[] args)
{
try{
Class1 t = new Class1();
t.CustomException(args[0]);
}catch(Exception e)
{
Console.WriteLine("Error: " + e);
}
}
}
Trong bài này, chúng ta tìm hiểu các đối tượng Exception và các khai báo
dùng để kiểm soát lỗi phát sinh trong khi thực thi chương trình.
- 80 -
NGUYỄN TRẦN MINH KHUÊ
CHƯƠNG 9
KHÔNG GIAN TÊN
VÀ THUỘC TÍNH
- 81 -
NGUYỄN TRẦN MINH KHUÊ
Trong những chương trước chúng ta tìm hiểu cách khai báo không gian tên
của .NET, bằng cách khai báo không gian tên sau đó sử dụng chung cho ứng
dụng.
Ngoài ra, bài học này cung cấp cho bạn cách khai báo và truy cập thuộc tính
trong class.
Các vấn đề chính sẽ được đề cập:
Không gian tên
Khai báo và sử dụng thuộc tính
Khi làm việc với một dự án lớn, có rất nhiều class được tạo ra từ nhiều
nhóm lập trình, đôi khi các class này không kết hợp thành một nhóm, để kết hợp
các class này lại với nhau bạn sử dụng không gian tên (namespace).
Namespace cho phép chúng ta tổ chức mã nguồn và bảo dảm rằng chúng
sẽ không dư thừa và đơn giản khi sử dụng lại trong một ứng dụng khác.
47.1. Khai báo namespace
Để khai báo namespace trong C#, bạn sử dụng cú pháp như sau:
namespace namespacename
{
/*Khai báo*/
}
Lưu ý rằng, namespace mặc định là public, chính vì vậy không cho phép
khai báo từ khoá public, protected hay private trước từ khoá namespace.
Chẳng hạn, có một số class như sau khai báo trên một hay nhiều tập tin
class:
}
public class myCom
{
}
public class myUtility
{
- 82 -
NGUYỄN TRẦN MINH KHUÊ
Sử dụng namespace để kết hợp các class trên lại với nhau bằng cách khai
báo như sau:
namespace mynamespace
{
public class myDatabase
{
}
public class myCom
{
}
public class myCommmon
{
}
public class myUtility
{
}
}
Namespace có thể khai báo lồng, điều này có nghĩa là khai báo một
Namespace trong một Namespace. Giả sử rằng, chúng ta muốn có hai
Namespace con trong mynamespace là mySQL và myAccess thì khai báo như
sau:
namespace mynamespace
{
namespace mySQL
{
public class mySQLDatabase
{
}
public class mySQLCom
{
}
public class mySQLCommmon
{
}
public class mySQLUtility
{
}
}
namespace myAccess
{
public class myAccessDatabase
{
- 83 -
NGUYỄN TRẦN MINH KHUÊ
}
public class myAccessCommmon
{
}
public class myAccessUtility
{
}
}
}
Tuy nhiên, bằng cách khai báo như sau bạn cũng có thể tạo ra một
namespace lồng trong namespace khác:
namespace mynamespce.mySQL
{
public class mySQLDatabase
{
}
public class mySQLCom
{
}
public class mySQLCommmon
{
}
public class mySQLUtility
{
Khi sử dụng class trong namespace đó thì bạn chỉ cần gọi đến tên class
muốn dùng, ví dụ sử dụng class có tên mySQLDatabase thì khai báo như sau:
namespace mynamespace
{
namespace mySQL
{
public class mySQLDatabase
{
}
...
public classMain
{
static void Main()
{
/*Khai báo class trong không gian
tên hiện hành*/
mySQLDatabase t = new
mySQLDatabase();
...
}
- 84 -
NGUYỄN TRẦN MINH KHUÊ
}
}
namespace myAccess
{
public class myAccessDatabase
{
}
...
}
}
Tuy nhiên, trong trường hợp sử dụng class của namespace khác trong
namespace hiện hành, bạn phải khai báo tên namespace đó như sau:
namespace mynamespace
{
namespace mySQL
{
public class mySQLDatabase
{
}
...
public classMain
{
static void Main()
{
/*Khai báo class của không gian tên
khác*/
myAccess.myAccessDatabase t = new
myAccess.myAccessDatabase();
...
}
}
}
namespace myAccess
{
public class myAccessDatabase
{
}
...
}
}
Do tên của namespace qua dài hay sử dụng class của namespace tên khác
như sau:
mynamespace.myAccess.myAccessDatabase
t = new mynamespace.myAccess.myAccessDatabase();
Thay vì khai báo chỉ định tên namespace và tên class như trên, bạn có thể
sử dụng chỉ mục như sau:
using mynamespace.myAccess;
...
- 85 -
NGUYỄN TRẦN MINH KHUÊ
Lưu ý rằng, chỉ mục namespace trong class phải được khai báo trên mọi
thành viên khác của class ví dụ:
using System;
using System.IO;
using mynamespace.myAccess;
namespace FirstCSharp
{
/// <summary>
/// Summary description for Class3.
/// </summary>
public class Class3
{
static void Main()
{
myAccessDatabase t = new
myAccessDatabase();
...
}
}
}
Ngoài cách sử dụng khai báo chỉ mục như trên, bạn có thể sử dụng bí danh
để khai báo namespace như sau:
using System;
using System.IO;
using ns=mynamespace.myAccess.
myAccessDatabase;
namespace FirstCSharp
{
/// <summary>
/// Summary description for Class3.
/// </summary>
public class Class3
{
static void Main()
{
ns t = new ns();
...
}
}
}
Trong trường hợp trong hai namespace có hai class trùng tên nhau, khi
khai báo để sử dụng phải chỉ định tên namespace của nó. Chẳng hạn, trong hai
namespace có tên mySQL và myAccess đều có class tên là Test, như vậy khi
khai báo bạn sử dụng cú pháp như sau:
using System;
- 86 -
NGUYỄN TRẦN MINH KHUÊ
using System.IO;
using mynamespace.mySQL;
using mynamespace.myAccess;
namespace FirstCSharp
{
/// <summary>
/// Summary description for Class3.
/// </summary>
public class Class3
{
static void Main()
{
Test t = new MyAccess.Test();
...
}
}
}
Khái niệm thuộc tính đã có trong ngôn ngữ lập trình Visual Basic, trong
C# một trường được khai báo và cho phép đọc hay gán giá trị gọi là thuộc tính
(properties).
Tương tự như trong ngôn ngữ lập trình C++, để khai báo thuộc tính trong
C# bạn dùng hai phương thức set và get như sau:
C# cung cấp hai loại thuộc tính là thuộc tính chỉ đọc và thuộc tính đọc và
ghi.
- 87 -
NGUYỄN TRẦN MINH KHUÊ
Một thuộc tính được xem là đọc và ghi là cho phép bạn gán (set) giá trị
vào thuộc tính hay lấy (get) giá trị ra từ thuộc tính. Để khai báo thuộc tính vừa
đọc và ghi bạn sử dụng cú pháp như sau:
Nếu muốn thuộc tính chỉ đọc, bạn chỉ sử dụng phương thức get như khai
báo như sau:
Sau khi khai báo thuộc tính, bạn có thể truy cập đến thuộc tính đế gán hay
lấy giá trị bằng cách khai báo như sau:
using System;
public class GetSetPro
{
int liA;
int liB=100;
public int getAndSet
{
get
{
return liA;
}
set
{
liA = value;
}
}
public int getOnly
{
get
{
return liB;
- 88 -
NGUYỄN TRẦN MINH KHUÊ
}
}
}
class UsePro
{
static void Main()
{
GetSetPro GS=new GetSetPro();
/*thuộc tính đọc và ghi */
GS.liA=1500;
Console.WriteLine(“liA={0}”,GS.liA);
/*thuộc tính chỉ đọc */
Console.WriteLine(“liA={0}”,GS.liB);
}
}
Trong bày này, chúng ta tìm hiểu cách cài đặt và sử dụng một không gian
tên trong chương trình.
Bằng cách khai báo thuộc tính với hai phương thức chính là get và set, bạn
cho phép gán giá trị từ bên ngoài vào biến hay lấy giá trị từ các trường này.
- 89 -
NGUYỄN TRẦN MINH KHUÊ
DIỄN GIẢI
- 90 -
NGUYỄN TRẦN MINH KHUÊ
Khi làm việc với ngôn ngữ lập trình C#, chúng ta cần quan tâm đến các ký
hiệu, ký tự đặc biệt và ghi chú trong chương trình.
Các vấn đề chính sẽ được đề cập:
Cú pháp
Ghi chú (Comment)
Dấu hiệu (Token)
Lỗi do người sử dụng định nghĩa
50. CÚ PHÁP
Tất cả các biểu thức điều kiện khai báo trong các phát biểu điều khiển
phải đóng bởi cặp dấu (), ví dụ như khai báo:
if(!(i==j))
{
Mọi câu lệnh phải được kết thúc bằng dấu ; chẳng hạn khai báo:
System.Console.WriteLine("C# Basic");
Bắt đầu class, phương thức, interface, namespace, ... đều bắt đầu dấu { và
kết thúc dấu }. Ngoài ra, trong phát biểu điều khiển có nhiều hơn một câu lệnh,
bạn cũng sử dụng cặp dấu trên.
51. GHI CHÚ
Để khai báo chi chú cho một câu diễn giải trong chương trình, bạn sử
dụng cặp dấu // trước đầu câu, ví dụ câu “Hello, world program” là chuỗi diễn
giải.
class Hello
{
static void Main() {
System.Console.WriteLine("C# Basic");
}
}
Trong trường hợp có một đoạn diễn giải liên tiếp trong chương trình, thay
vì sử dụng cặp dấu // để ghi chú từng câu, chúng ta sử dụng cặp dấu /* kế đến nội
dung và kết thúc dấu */ . Chẳng hạn, chúng ta khai báo hai câu diễn giải “
/*
- 91 -
NGUYỄN TRẦN MINH KHUÊ
C# Basic, C# Program
This program writes “C#, SQL Server”
to the console
*/
using System;
class Hello
{
static void Main() {
Console.WriteLine("C#, SQL Server");
}
}
Lưu ý rằng, bạn có thể ghi chú ngay trên cùng với câu lệnh của chương
trình, ví dụ như khai báo sau:
Các dấu hiệu thường sử dụng trong chương trình C# bao gồm các ký tự
đặc biệt như dấu \, “, @.
Trong chương trình C# khi xuất chuỗi giá trị có các ký tự đặc biệt như dấu
\, “ thì bạn sử dụng thêm dấu \ để trình biên dịch biết rằng đây là chuỗi kết xuất.
Chẳng hạn, khai báo C:\test.txt:
using System;
class Class1
{
static void Test() {
Console.WriteLine("C:\\test.txt");
}
}
Hoặc khi chuỗi muốn xuất hiện có dấu ", bạn khai báo trong chương trình
C# với đấu \ trước dấu ", giả sử xuất ra màn hình chuỗi This is "C#" như sau:
using System;
class Class1
{
static void Test(bool f) {
if (f)
Console.WriteLine("This is \"C#\"");
}
}
- 92 -
NGUYỄN TRẦN MINH KHUÊ
Trong trường hợp đặt muốn đặt tên biến, class, các định danh khác trùng
với các từ khoá của C#, bạn sử dụng ký tự @ trước định danh. Chẳng hạn, khai
báo class có tên class hay biến có tên là int, bạn có thể sử dụng ký tự @ như sau:
using System;
class @class
{
public static void @static(bool @bool) {
if (@bool)
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
class Class1
{
static void M() {
cl\u0061ss.st\u0061tic(true);
}
}
- 93 -
NGUYỄN TRẦN MINH KHUÊ
- 94 -