Chuong 2 - Ngon Ngu Lap Trinh CSharp

203
Ngôn ngữ lập trình C# GV: Tôn Quang Toại

Transcript of Chuong 2 - Ngon Ngu Lap Trinh CSharp

Page 1: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Ngôn ngữ lập trình C#

GV: Tôn Quang Toại

Page 2: Chuong 2 - Ngon Ngu Lap Trinh CSharp

2

Nội dung

Các thành phần cơ bản của ngôn ngữ Hệ thống kiểu Xuất/Nhập và chuyển đổi kiểu dữ liệu – chương trình

đầu tiên và giải thích Các lệnh điều khiển: if, switch, goto, for, do…while,

foreach Lớp, đối tượng và struct Đơn thừa kế Interface Property, Mảng và Indexer Lớp collection và exception Delegate và event

Page 3: Chuong 2 - Ngon Ngu Lap Trinh CSharp

3

Ví dụ đầu tiên {1}

public class Hello1 {

public static void Main() {

System.Console.WriteLine("Hello, World!"); }

}

using System; public class Hello2 {

public static void Main() {

Console.WriteLine("Hello, World!"); }

}

Page 4: Chuong 2 - Ngon Ngu Lap Trinh CSharp

4

Ví dụ đầu tiên {2}

using System; public class Hello3 {

public static void Main() {

Console.WriteLine("Hello, World!");Console.WriteLine(“So tham so: {0}: ", args.Length ); for (int i=0; i < args.Length; i++) {

Console.WriteLine("{0}", args[i]); }

} }

Page 5: Chuong 2 - Ngon Ngu Lap Trinh CSharp

5

Ví dụ đầu tiên {3}

using System; public class Hello3 {

public static int Main() {

Console.WriteLine("Hello, World!");return 0;

} }

Page 6: Chuong 2 - Ngon Ngu Lap Trinh CSharp

6

Ví dụ đầu tiên {4}

Hàm Main()• entry point của chương trình

• Được khai báo bên trong class hay struct

• Phải Static

• Kiểu trả về void hay int

• Có thể có hay không có tham số

Page 7: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Các thành phần cơ bản của ngôn ngữ

Page 8: Chuong 2 - Ngon Ngu Lap Trinh CSharp

8

Identity {1}

Identity – định danh: Tên lớp, tên phương thức, tên biến, tên đối tượng, tên hằng, tên kiểu, …

Quy tắc tạo định dang trong C#: • Ký tự đầu tiên: chữ, ký tự gạch dưới, ký tự @

• Các ký tự còn lại: chữ, số, ký tự gạch dưới

Page 9: Chuong 2 - Ngon Ngu Lap Trinh CSharp

9

Identity {2}

Một danh định có thể được đặt theo hai quy tắc • Pascal: Ký tự đầu tiên của mỗi từ viết HOA• Camel: Giống Pascal nhưng ký đầu tiên của danh định được

viết thường

Quy tắc đặt tên định danh• Pascal

– NameSpace– Class– Interface– Public Method/Field– Constant

• Camel– Otherss

Page 10: Chuong 2 - Ngon Ngu Lap Trinh CSharp

10

Identity {2}

Quy tắc đặt tên định danh• Namespace

– Pascal– Tên của công ty + tên đề án cách nhau bằng ký

tự dấu chấm “.”

Page 11: Chuong 2 - Ngon Ngu Lap Trinh CSharp

11

Identity {3}

Quy tắc đặt tên định danh• Interface

– Pascal– Bắt đầu bằng ký tự I

• Lớp– Pascal– Danh từ– Ví dụ:

Line, AudioSystem

Page 12: Chuong 2 - Ngon Ngu Lap Trinh CSharp

12

Identity {4}

Quy tắc đặt tên định danh• Field

– Camel– Không chứa tên lớp– Ví dụ:

line, audioSystem

– Những biến có vai trò thì kết hợp vai trò với kiểu– Ví dụ:

Point startingPoint; Name loginName;

Page 13: Chuong 2 - Ngon Ngu Lap Trinh CSharp

13

Identity {5}

Quy tắc đặt tên định danh• Field

– Những biến chung chung nên có cùng tên với kiểu– Ví dụ:

Topic topic; Database database;

– Những biến kiểu control: list, text, …: Nên kèm theo kiểu ở suffix

– Ví dụ: leftScrollbar

Page 14: Chuong 2 - Ngon Ngu Lap Trinh CSharp

14

Identity {6}

Quy tắc đặt tên định danh• Field

– Mảng hay collection: Dùng danh từ số nhiều– Ví dụ:

Point[] points;

– Biến đếm: Dùng prefix: n, cnt– Ví dụ:

nPoints; cntPoint;

Page 15: Chuong 2 - Ngon Ngu Lap Trinh CSharp

15

Identity {7}

Quy tắc đặt tên định danh• Phương thức

– Pascal– Động từ– Không chứa tên lớp– Khi phương thức truy cập field

Get/Set + field Dùng property

– Ví dụ: employee.getName();

Page 16: Chuong 2 - Ngon Ngu Lap Trinh CSharp

16

Identity {8}

Quy tắc đặt tên định danh• Phương thức

– Khi phương thức trả về kiểu bool: Dùng prefix: Is, has, can, should

– Ví dụ: bool IsOpen(); bool ShouldAbort();

– Khi phương thức Tính toán: Dùng prefix: Compute Tìm kiếm: Dùng prefix: Find Thiết lập: Dùng prefix: Iniitialize

Page 17: Chuong 2 - Ngon Ngu Lap Trinh CSharp

17

Identity {9}

Quy tắc đặt tên định danh• Đối số của phương thức

– Pascal

• Biến lặp trong phương thức– i, j, k, …

• Hằng giá trị– Viết HOA tất cả ký tự và có thể dùng thêm ký tự

Underscore

• Từ viết tắt– Chỉ viết HOA ký tự đầu– Ví dụ:– OpenDvdPlayer()

Page 18: Chuong 2 - Ngon Ngu Lap Trinh CSharp

18

Biến – Biến hằng

Biến - Việc tạo biến trong C# có một số quy tắc sau:• Biến đươc khai báo trong khối cha thì không

được khai báo lại trong khối con và ngược lại.• Biến được khai báo trong vòng lặp for chỉ có

tác dụng trong vòng lặp for• Biến phải được khởi tạo trước khi sử dụng

Biến hằng:const int x =555;

Page 19: Chuong 2 - Ngon Ngu Lap Trinh CSharp

19

Từ khóa - keyword

Có thể dùng "at" sign (@) ở đầu từ khóa để tạo identity

abstract as base bool break

by3 byte case catch char

checked class const continue decimal

default delegate do double descending3

explicit event extern else enum

false finally fixed float for

foreach from3 goto group3 if

implicit in int interface internal

into3 is lock long new

null namespace object operator out

override orderby3 params private protected

public readonly ref return switch

struct sbyte sealed short sizeof

stackalloc static string select3 this

throw true try typeof uint

ulong unchecked unsafe ushort using

var3 virtual volatile void while

where3 yield2      

2 - C# 2.0 Keyword - 3 - C# 3.0 Keyword

Page 20: Chuong 2 - Ngon Ngu Lap Trinh CSharp

20

Các toán tử C#

Loại toán tử Toán tử

Số học + - * / %

Logical (boolean và bitwise) & | ^ ! ~ && || true false

Nối chuỗi +

Tăng, giảm ++ --

Dịch chuyển bit << >>

Quan hệ == != < > <= >=

Gán = += -= *= /= %= &= |= ^= <<= >>= ?? (3.0)

Truy cập thành viên .

Chỉ mục, chỉ số []

Ép kiểu ()

Điều kiện ?:

Nối và gở bỏ delegate + -

Tạo đối tượng new

Thông tin kiểu as is sizeof typeof

Điều khiển ngoại lệ tràng bộ nhớ checked unchecked

Indirection và Address * -> [] &

Lambda => (3.5)

Page 21: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Hệ thống kiểu .NET

Page 22: Chuong 2 - Ngon Ngu Lap Trinh CSharp

22

Mọi thứ đều là đối tượng {1}

Vấn đề: • Phần lớn các ngôn ngữ lập trình hướng đối

tượng có hai kiểu riêng biệt:– Các kiểu của riêng ngôn ngữ (kiểu cơ bản): ký

tự, chuỗi, số, … – Các kiểu do lập trình viên tạo ra (các lớp)

• Việc phân thành hai loại như thế một số vấn đề: Sự tương thích

Page 23: Chuong 2 - Ngon Ngu Lap Trinh CSharp

23

Mọi thứ đều là đối tượng {2}

Vấn đề

• Ví dụ 1: Chúng ta muốn tạo một tập các số nguyên int và một tập các số thực double

• Ví dụ 2: Chúng ta muốn tạo một method có các tham số kiểu bất kỳ

Page 24: Chuong 2 - Ngon Ngu Lap Trinh CSharp

24

Mọi thứ đều là đối tượng {3}

class CType{

public:CType(int data);CType(double data);CType(float data);

…};

class A{

public:void MyMethod(CType &type);

};

Page 25: Chuong 2 - Ngon Ngu Lap Trinh CSharp

25

Mọi thứ đều là đối tượng {4}

.NET đã giúp chúng ta giải quyết vấn đề này dễ dàng hơn. • Mọi thứ trong CTS đều là đối tượng (không có

kiểu cơ bản nào cho từng ngôn ngữ trong .NET – tách kiểu ra khỏi ngôn ngữ)

• Tất cả đối tượng ngầm định được dẫn xuất từ duy nhất một lớp cơ sở được định nghĩa trong CTS: System.Object

Page 26: Chuong 2 - Ngon Ngu Lap Trinh CSharp

26

Kiểu tham trị và kiểu tham chiếu {1}

Page 27: Chuong 2 - Ngon Ngu Lap Trinh CSharp

27

Kiểu tham trị và kiểu tham chiếu {2}

Kiểu giá trị (value type):• Được cấp phát trên stack

• Ví dụ:– System.Int32 a = 5;

• Các loại kiểu giá trị:– enum– struct– kiểu cơ bản: int, double, …

Page 28: Chuong 2 - Ngon Ngu Lap Trinh CSharp

28

Kiểu tham trị và kiểu tham chiếu {3}

Kiểu tham chiếu (reference type)• Các biến thuộc các kiểu tham khảo được cấp

phát trên vùng nhớ stack và biến trỏ đến một đối tượng đã được cấp trên vùng nhớ heap.

• Các biến thuộc các kiểu tham khảo có thể chứa giá trị null để báo rằng không trỏ đến đối tượng nào trên vùng nhớ heap

Page 29: Chuong 2 - Ngon Ngu Lap Trinh CSharp

29

Kiểu tham trị và kiểu tham chiếu {4}

Kiểu tham chiếu (reference type)• Ví dụ :

– System.String s = “Hello, World”

• Các loại kiểu tham khảo:– Lớp– Mảng– Interface– Delegate

Page 30: Chuong 2 - Ngon Ngu Lap Trinh CSharp

30

So sánh kiểu giá trị và kiểu tham chiếu

Page 31: Chuong 2 - Ngon Ngu Lap Trinh CSharp

31

Boxing và Unboxing {1}

Vấn đề: việc tách thành hai loại kiểu như trên thì làm thế nào hệ thống hoạt động hiệu quả • Boxing: là chuyển từ kiểu giá trị sang kiểu

tham khảo

• Unboxing: là chuyển từ kiểu kiểu tham khảo sang giá trị

Page 32: Chuong 2 - Ngon Ngu Lap Trinh CSharp

32

Boxing và Unboxing {2}

Boxing• Ví dụ:

– int a = 55;– object o = a;

• Quá trình hoạt động của boxing– Trước hết một vùng nhớ được cấp phát trên vùng nhớ

heap để tạo đối tượng o– Sau đó giá trị của biến kiểu giá trị được sao chép sang

vùng nhớ heap đó– Cuối cùng địa chỉ của đối tượng được cấp phát trên

heap được đặt vào vùng nhớ trên stack

Page 33: Chuong 2 - Ngon Ngu Lap Trinh CSharp

33

Boxing và Unboxing {3}

Unboxing• Ví dụ:

– int a = 55;– object o = a;– int b = (int)o;

Chú ý: • Boxing là không cần ép kiểu• Unboxing phải ép kiểu

• Quá trình hoạt động của boxing– Trước hết runtime kiểm tra xem địa chỉ trên stack có trỏ đến đối tượng

hợp lệ không và kiểm tra xem kiểu đối tượng có thể được chuyển sang kiểu giá trị không. Nếu không sẽ nén ra một ngoại lệ InvalidCastException

– Một con trỏ đến giá trị bên trong đối tượng được trả về. Chú ý rằng boxing tạo một bản sao của kiểu được chuyển đổi, còn unboxing thì không làm thế.

Page 34: Chuong 2 - Ngon Ngu Lap Trinh CSharp

34

Kiểu và bí danh {1}

CTS định nghĩa các kiểu cho tất cả các ngôn ngữ lập trình trên .NET như System.Int32, System.String, … nhưng mỗi ngôn ngữ lại chọn các bí danh trên các kiểu này

Page 35: Chuong 2 - Ngon Ngu Lap Trinh CSharp

35

Kiểu và bí danh {2}

Kiểu C# và kiểu .NET Framework có thể dùng thay thế cho nhau

Để hiển thị kiểu .NET Framework của kiểu C# chúng ta dùng• Phương thức obj.GetType()

VD: int x= 5;x.GetType();

• Toán tử typeof(type) VD: typeof(int);

Kiều C# Kiểu .NET Framework

bool System.Boolean

byte System.Byte

sbyte System.SByte

char System.Char

decimal System.Decimal

double System.Double

float System.Single

int System.Int32

uint System.UInt32

long System.Int64

ulong System.UInt64

object System.Object

short System.Int16

ushort System.UInt16

string System.String

Page 36: Chuong 2 - Ngon Ngu Lap Trinh CSharp

36

Kiểu số nguyên

Kiểu Miền giá trị Kích thước (bit)

sbyte -128 to 127 8

byte 0 to 255 8

char U+0000 to U+ffff 16

short -32,768 to 32,767 16

ushort 0 to 65,535 16

int -2,147,483,648 to 2,147,483,647 32

uint 0 to 4,294,967,295 32

long-9,223,372,036,854,775,808 to

9,223,372,036,854,775,80764

ulong 0 to 18,446,744,073,709,551,615 64

Page 37: Chuong 2 - Ngon Ngu Lap Trinh CSharp

37

Kiểu số thực

Kiểu Miền giá trị Độ chính xác Kích thước (bit)

float ±1.5e−45 to ±3.4e38 7 digits 32

double ±5.0e−324 to ±1.7e308 15-16 digits 64

Page 38: Chuong 2 - Ngon Ngu Lap Trinh CSharp

38

Kiểu số decimal

So với các kiểu số thực, decimal có: • Độ chính xác cao hơn• Miền giá trị nhỏ hơn

Phù hợp cho các ứng dụng tài chính, tiền tệ Nếu muốn một số thực được xem như là decimal

dùng hậu tố m hay Mdecimal myMoney = 300.5m;

Số nguyên: tự chuyển đổidecimal myMoney = 300;

Chuyển đổi giữa Số thực và decimal ép kiểudecimal myMoney = 99.9m; double x = (double)myMoney; myMoney = (decimal)x;

Kiểu Miền giá trị Độ chính xác Kích thước (bit)

decimal ±1.0 × 10−28 to ±7.9 × 1028 28-29 128

Page 39: Chuong 2 - Ngon Ngu Lap Trinh CSharp

39

Kiểu ký tự

Hằng ký tự: • ‘a’

• ‘\uxxxx’: x là số hexa

Kiểu Kích thước (bit)

char 16

Page 40: Chuong 2 - Ngon Ngu Lap Trinh CSharp

40

Kiểu chuỗi

Đặc điểm string• Chuỗi ký tự unicode• Kiểu tham chiếu• Kích thước cố định

Hằng chuỗi:• “”• @””

Phép toán trên string• Toán tử ==, != dùng để so sánh các giá trị của string• +, []

Page 41: Chuong 2 - Ngon Ngu Lap Trinh CSharp

41

Kiểu bool

Miền giá trị: true, false Không thể chuyển bool sang kiểu khác

Kiểu Kích thước (bit)

bool 1

Page 42: Chuong 2 - Ngon Ngu Lap Trinh CSharp

42

Chuyển kiểu ngầm định

Không có chuyển kiểu ngầm định • Sang kiểu char

• Giữa số thực và decimal

Page 43: Chuong 2 - Ngon Ngu Lap Trinh CSharp

43

Các giá tri mặc nhiên của kiểu giá trị {1}

Khi dùng constructor mặc nhiên, các biến thuộc kiểu dữ liệu giá trị sẽ có giá trị mặc nhiên

VD: int myInt = new int(); int myInt = 0;

Chú ý: Không được sử dụng biến chưa khởi tạo

Page 44: Chuong 2 - Ngon Ngu Lap Trinh CSharp

44

Các giá tri mặc nhiên của kiểu giá trị {2}

kiểu giá trị Giá trị mặc nhiên

bool false

byte 0

char '\0'

decimal 0.0M

double 0.0D

enum Giá trị được sinh bởi biểu thức (E)0, trong đó E là identity của enum.

float 0.0F

int 0

long 0L

sbyte 0

short 0

structGiá trị được sinh bằng cách thiết lập tất cả field kiểu giá trị thanh giá trị

mặc nhiên, tất cả field kiểu tham chiếu thành null.

uint 0

ulong 0

ushort 0

Page 45: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Xuất/Nhập và chuyển đổi kiểu dữ liệuchương trình đầu tiên

Page 46: Chuong 2 - Ngon Ngu Lap Trinh CSharp

46

Chương trình đầu tiên

namespace CSharp

     class Program

     {

         public static void Main()

         {

// Xuat du lieu ra man hinh

             System.Console.WriteLine("Hello, World");

        }

     }

}

Page 47: Chuong 2 - Ngon Ngu Lap Trinh CSharp

47

Giải thích – Cách viết code

One-Stop Programming• Các phương thức được định nghĩa ngay trong

thân của lớp

Page 48: Chuong 2 - Ngon Ngu Lap Trinh CSharp

48

Giải thích – Namespace {1/2}

Namespace• Chức năng cơ bản là nhóm các thành phần

(lớp, struct, namespace khác, …) dưới 1 cái tên để tránh việc trùng tên của các thành phần

• Cú pháp:

namespace <namespace_name> 

    <namespace-body> 

}

Page 49: Chuong 2 - Ngon Ngu Lap Trinh CSharp

49

Giải thích – Namespace {2/2}

Chú ý:• Namespace có thể lồng namespace khác• Các thành phần trong các namespace khác nhau có

thể có tên giống nhau Để truy cập các thành phần bên trong namespace

chúng ta dùng cú pháp

Để viết code dễ dàng hơn chúng ta có thể dùng câu lệnh using• Cú pháp

<namespace_name1>.<namespace_name2>…<class>

using <NamespaceName>;

Page 50: Chuong 2 - Ngon Ngu Lap Trinh CSharp

50

Giải thích – Chú thích

Giống C/C++

//

/**/

Page 51: Chuong 2 - Ngon Ngu Lap Trinh CSharp

51

Giải thích – Lớp và thành viên

Một lớp C# có thể chứa các thành viên • Constants

• Fields

• Methods

• Properties

• Events

• Indexers

• Operators

• instance constructors

• destructors, static constructors và các kiểu khai báo lồng nhau

Page 52: Chuong 2 - Ngon Ngu Lap Trinh CSharp

52

Giải thích – Phương thức Main

Phải có ít nhất một lớp chứa phương thức Main• public static void Main()

• public static void Main( string[] args )

• public static int Main()

• public static int Main( string[] args )

Page 53: Chuong 2 - Ngon Ngu Lap Trinh CSharp

53

Giải thích – Xuất dữ liệu {1/3}

Nhập dữ liệu từ bàn phím và xuất dữ liệu ra màn hình trong C# có thể dùng các phương thức tĩnh trong lớp: System.Console

Xuất dữ liệu lên màn hình• Cú pháp 1:

void Write(data);

void WriteLine(data);

Page 54: Chuong 2 - Ngon Ngu Lap Trinh CSharp

54

Giải thích – Xuất dữ liệu {2/3}

Xuất dữ liệu lên màn hình• Cú pháp 2:

• Trong đó:– format: chứa chuỗi định dạng– arg là mảng các đối tượng xuất sử dụng chuỗi

định dạng

void Write(string format, params object[]arg);

void WriteLine(string format, params object[]arg);

Page 55: Chuong 2 - Ngon Ngu Lap Trinh CSharp

55

Giải thích – Xuất dữ liệu {3/3}

Xuất dữ liệu lên màn hình• format là một chuỗi bình thường và có thể có

thêm 1 hay nhiều phần định dạng có cú pháp sau

– Cú pháp:

– Trong đó: index: Số thứ tự của đối số, bắt đầu từ 0 alignment: độ rộng, M>0 canh phải, M<0 canh trái formatString: C hay c, D hay d, E hay e, F hay f, …

{ index[,alignment][:formatString]}

Page 56: Chuong 2 - Ngon Ngu Lap Trinh CSharp

56

Giải thích – Nhập dữ liệu

Nhập dữ liệu từ bàn phím• Cú pháp:

int Read();

string ReadLine();

Page 57: Chuong 2 - Ngon Ngu Lap Trinh CSharp

57

Lớp Convert

Đây là lớp tiện ích cho việc chuyển đổi giữa các dữ liệu có các kiểu dữ liệu khác nhau

Phương thức Ý nghĩa

ToBoolean Chuyển một giá trị sang giá trị Boolean

ToByte Chuyển một giá trị sang giá trị số nguyên 8-bit không dấu

ToChar Chuyển một giá trị sang giá trị ký tự unicode

ToDateTime Chuyển một giá trị sang giá trị DateTime.

ToDecimal Chuyển một giá trị sang giá trị Decimal.

ToDouble Chuyển một giá trị sang giá trị số thực có độ chính xác gấp đôi 8 byte

ToInt16 Chuyển một giá trị sang giá trị số nguyên 16-bit có dấu

ToInt32 Chuyển một giá trị sang giá trị só nguyên 32-bit có dấu

ToInt64 Chuyển một giá trị sang giá trị số nguyên 64-bit có dấu

ToSByte Chuyển một giá trị sang giá trị số nguyên 8-bit có dấu

ToSingle Chuyển một giá trị sang giá trị số thực có độ chính xác đơn

ToString Chuyển một giá trị sang giá trị một chuỗi

ToUInt16 Chuyển một giá trị sang giá trị số nguyên 16-bit không dấu

ToUInt32 Chuyển một giá trị sang giá trị số nguyên 32-bit không dấu

ToUInt64 Chuyển một giá trị sang giá trị số nguyên 64-bit không dấu

Page 58: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Các lệnh điều khiển: if, switch, goto, for, do…while, foreach

Page 59: Chuong 2 - Ngon Ngu Lap Trinh CSharp

59

Câu lệnh if, switch

Cú pháp 1

Cú pháp 2

if (expression)

{

Các câu lệnh

}

if (expression)

{

Các câu lệnh A;

}

else

{

Các câu lệnh B;

}

Page 60: Chuong 2 - Ngon Ngu Lap Trinh CSharp

60

Câu lệnh if, switch {1/2}

Câu lệnh if• Cú pháp 1

• Cú pháp 2

if (expression)

{

Các câu lệnh

}

if (expression)

{

Các câu lệnh A;

}

else

{

Các câu lệnh B;

}

Page 61: Chuong 2 - Ngon Ngu Lap Trinh CSharp

61

Câu lệnh if, switch {2/2}

Câu lệnh switch• Cú pháp

Chú ý:• Expression phải thuộc các kiểu:

– số nguyên, char, string, enum

• Luôn cung cấp “lệnh nhảy” cho mỗi case (kể cả default)

• Nếu thân case là câu lệnh rỗng thì không cần lệnh nhảy

switch (expression){

case const_expression1:

break;

case const_expression2:

break;

case const_expressionN:

break;

default:

break;

}

Page 62: Chuong 2 - Ngon Ngu Lap Trinh CSharp

62

Câu lệnh nhảy

Câu lệnh break, continue giống C/C++ Câu lệnh goto

• Cú pháp

goto label;

goto case constExpression

goto default;

Page 63: Chuong 2 - Ngon Ngu Lap Trinh CSharp

63

Câu lệnh lặp {1/3}

Câu lệnh for• Cú pháp

Câu lệnh while• Cú pháp

for (initialization; BooleanExpression; step)

{

Các câu lệnh

}

while (BooleanExpression)

{

Các câu lệnh

}

Page 64: Chuong 2 - Ngon Ngu Lap Trinh CSharp

64

Câu lệnh lặp {2/3}

Câu lệnh do...while• Cú pháp

do

{

Các câu lệnh

} while (BooleanExpression);

Page 65: Chuong 2 - Ngon Ngu Lap Trinh CSharp

65

Câu lệnh lặp {3/3}

Câu lệnh foreach• Cú pháp

• Trong đó:– type là kiều của biến variableName– expression là đối tượng collection hay mảng

foreach (type variableName in expression)

{

Các câu lệnh

}

Page 66: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Lớp, đối tượng và struct

Page 67: Chuong 2 - Ngon Ngu Lap Trinh CSharp

67

Định nghĩa lớp cơ bản

Định nghĩa lớp• Cú pháp:

Các thành viên của class • Field• Method• Property• Constant• Indexer• Event• Operator

[attributes] [modifiers] class <className> [: baseClassName] 

{

    [class-body]

}[;]

Page 68: Chuong 2 - Ngon Ngu Lap Trinh CSharp

68

Bổ từ truy cập

Bổ từ truy cập• public

• protected

• private

• internal

DEFAULT: private

class AccessModsInCSharp {     

public int a;     public int b;     public int c;     protected int d;     protected int e;

}

Page 69: Chuong 2 - Ngon Ngu Lap Trinh CSharp

69

Lớp

Field• Khai báo thành viên dữ liệu giống như khai báo biến

• Cú pháp: <type> <name>;

• Trong đó <type> có thể là– Kiểu cơ sở: char, int, float, double, …– Enum– Struct– Class – Event

Page 70: Chuong 2 - Ngon Ngu Lap Trinh CSharp

70

Dữ liệu của lớp - Field

Field• Thành viên dữ liệu có thể là một đối tượng

của lớp đang định

• Có thể vừa khai báo, vừa khởi tạo dữ liệu cho thành viên dữ liệu

Page 71: Chuong 2 - Ngon Ngu Lap Trinh CSharp

71

Phương thức

Phương thức và tham số• Định nghĩa phương thức trong C# chí có 1

cách: Thân của phương thức nằm trong lớp

• Có hai loại tham số phương thức– Tham số giá trị: không có modefier – Tham số tham chiếu: ref, out, params

Page 72: Chuong 2 - Ngon Ngu Lap Trinh CSharp

72

Phương thức

Phương thức với tham số params• Cú pháp

• Chú ý:– Khi dùng từ khóa params thì mảng theo

params là là tham số cuối cùng của phương thức.

class ClassName()

{

Method(…, params type[] variableName)

{

}

}

Page 73: Chuong 2 - Ngon Ngu Lap Trinh CSharp

73

Phương thức

Phương thức với tham số ref• Cú pháp class ClassName()

{

Method(ref type variableName)

{

}

}

Page 74: Chuong 2 - Ngon Ngu Lap Trinh CSharp

74

Phương thức

Phương thức với tham số ref• Cú pháp: sử dụng phương thức ref

• Chú ý – Tham số thực phải được khởi tạo trước khi gọi

phương thức.– Mọi thay đổi giá trị trong tham số hình thức đều

thay đổi giá trị trong tham số thực.– Giá trị của tham số thực được chuyển đến

tham số hình thức.

variableName = value;

Method(ref variableName);

Page 75: Chuong 2 - Ngon Ngu Lap Trinh CSharp

75

Phương thức

Phương thức với tham số out • Cú pháp class ClassName()

{

Method(out type variableName)

{

variableName = value;

}

}

Page 76: Chuong 2 - Ngon Ngu Lap Trinh CSharp

76

Phương thức

Phương thức với tham số out • Cú pháp: sử dụng phương thức out

• Chú ý– Tham số thực không nhất thiết phải được khởi tạo trước

khi gọi phương thức.– Tham số hình thức trong phương thức phải được gán

giá trị trước khi phương thức kết thúc– Giá trị của tham số thực không được chuyển đến tham

số hình thức, vì vậy không được dùng tham số hình thức trong hàm nếu chưa khởi tạo.

//variableName = value;

Method(out variableName);

Page 77: Chuong 2 - Ngon Ngu Lap Trinh CSharp

77

Phương thức

Method overloading• Phương thức có cùng tên phương thức nhưng

khác nhau về chữ ký phương thức.

Chữ ký phương thức: • Số lượng các tham số,

• Kiểu dữ liệu của các tham số và

• Thứ tự của các tham số.

Page 78: Chuong 2 - Ngon Ngu Lap Trinh CSharp

78

Phương thức Toán tử

Operator Overloading• Toán tử 1 ngôi

• Toán tử 2 ngôi

+ - ! ~

++ -- true false

+ - * / % &

| ^ << >> == !=

> < >= <=

Page 79: Chuong 2 - Ngon Ngu Lap Trinh CSharp

79

Phương thức Toán tử

Cú phápusing System;public class Distance{ int longitude, latitude;

public Distance() { longitude = 0; latitude = 0; }

public Distance(int longitude, int latitude) {

this.longitude = longitude;this.latitude = latitude;

}

public static Distance operator - (Distance first, Distance second) {

return new Distance(first.longitude - second.longitude, first.latitude - second.latitude); }}

public static retval operator op (object1 [, object2])

Page 80: Chuong 2 - Ngon Ngu Lap Trinh CSharp

80

Phương thức Toán tử

Tất cả các phương thức toán tử được định nghĩa: public và static

Khi overload toán tử 2 ngôi phép gán kết hợp được tự động overload

Toán tử so sánh (>, <, >=, <=, ==, !=) phải overload từng cặp

Nếu toán tử == và != được overload phải overload phương thức Equals() và GetHashCode()

Page 81: Chuong 2 - Ngon Ngu Lap Trinh CSharp

81

Phương thức Constructor

Constructor • Cú pháp

• Chú ý– Construtor được gọi tự động khi một instance của lớp

được tạo. Không thể gọi phương thức constructor rõ ràng.

– Các constructor có thể được đa năng hóa để cung cấp sự đa dạng cho việc khởi tạo đối tượng.

– Phương thức constructor có thể gọi các phương thức construtor khác

class ClassName

{

public ClassName(…)

{….}

}

Page 82: Chuong 2 - Ngon Ngu Lap Trinh CSharp

82

Phương thức Destructor

Destructor • Cú pháp

• Chú ý– Không có bất kỳ tham số nào– Được gọi bởi Garbage Collector - GC

class ClassName

{

public ~ClassName(…)

{….}

}

Page 83: Chuong 2 - Ngon Ngu Lap Trinh CSharp

83

Đối tượng

Tạo đối tượng với từ khóa new • Khai báo một biến class

– Cú pháp

• Tạo một đối thật sự – Cú pháp

<ClassName> <ObjectName>;

<ObjectName> = new <ClassName>(…);

<ClassName> <ObjectName> = new <ClassName>(…);

Page 84: Chuong 2 - Ngon Ngu Lap Trinh CSharp

84

Đối tượng

Truy cập thành viên class • Cú pháp

• Trong C# cũng có con trỏ this giống C++– Cú pháp

ObjectName.Method(params);

ObjectName.Field;

this.member

Page 85: Chuong 2 - Ngon Ngu Lap Trinh CSharp

85

Các thành phần khác của lớp

Field và Phương thức tĩnh • Cú pháp class ClassName

{

public static type variableName;

public static type Method(…)

{

}

}

Page 86: Chuong 2 - Ngon Ngu Lap Trinh CSharp

86

Các thành phần khác của lớp

Field và Phương thức tĩnh• Cú pháp: Gọi field và phương thức tĩnh

• Chú ý– Nếu không khai báo public thì phương

thức/field tĩnh chỉ được dùng cho các phương thức của lớp.

– Nếu phương thức gọi phương thức/field tĩnh thì dùng tên phương thức hay tên field không cần thông qua tên lớp

ClassName.Method(…);

ClassName.variableName;

Page 87: Chuong 2 - Ngon Ngu Lap Trinh CSharp

87

Các thành phần khác của lớp

Constant• Hằng là một field có giá trị không thay đổi

trong chu kỳ sống của đối tượng

• Ví dụ: const int x = 5;

• Quy tắc: – Field hằng là field có giá trị được thiết lập lúc

biên dịch– Field hằng mặc nhiên là tĩnh

Page 88: Chuong 2 - Ngon Ngu Lap Trinh CSharp

88

Các thành phần khác của lớp

Field Read-Only• Để field có giá trị được trì hoãn cho đến khi

chương trình bắt đầu chạy (khi đối tượng của lớp chứa field được tạo) chúng ta dùng field dạng readonly

• Giá trị của field được khởi tạo trong constructor

class CaptureApp{ public readonly int screenColor;

public CaptureApp(){

screenColor=65536;}

}

Page 89: Chuong 2 - Ngon Ngu Lap Trinh CSharp

89

Các thành phần khác của lớp

Constructor tĩnh• Nếu một field là tĩnh thì phải có phương thức

constructor tĩnh.

• Constructor tĩnh là constructor để khởi tạo các field tĩnh và readonly

class CaptureApp{ public readonly int screenColor;

static CaptureApp(){

screenColor=65536;}

}

Page 90: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Thừa kế

Page 91: Chuong 2 - Ngon Ngu Lap Trinh CSharp

91

Định nghĩa thừa kế

Định nghĩa • Cú pháp

Đơn thừa kế • C# không hổ trợ đa thừa kế thông qua dẫn

xuất• Tập hợp các đặc tính hành vi của các thực thể

được hiện thực bằng đa thừa kế giao diện

class DerivedClass : BaseClass{

…}

Page 92: Chuong 2 - Ngon Ngu Lap Trinh CSharp

92

Gọi Construtor của lớp cơ sở

Tất cả các constructor trong C# có lời gọi constructor của lớp cơ sở

Bộ khởi tạo giúp chúng ta quyết định lớp nào và constructor nào muốn gọi. • base(…)

• this(…)

class ClassName{

public ClassName(type obj, …):base(…){….}

public ClassName(type obj, …):this(…)

{….}

}

Page 93: Chuong 2 - Ngon Ngu Lap Trinh CSharp

93

Phương thức “new”

Phương thức trong lớp cơ sở và lớp dẫn xuất có thể trùng tên

Trình biên dịch sinh ra warning message cảnh báo IdentifierToken.Name ẩn Token.Name

class Token {

⋮public string Name() { ... }

} class IdentifierToken : Token {

⋮public string Name() { ... }

}

Page 94: Chuong 2 - Ngon Ngu Lap Trinh CSharp

94

Phương thức “new”

Được dùng như là 1 toán tử hay 1 modifier new được dùng để ẩn đi thành viên được

thừa kế từ lớp cơ sở Một phương thức không thể đồng thời có

new và overrideclass Token {

⋮public string Name() { ... }

} class IdentifierToken : Token {

⋮new public string Name() { ... }

}

Page 95: Chuong 2 - Ngon Ngu Lap Trinh CSharp

95

Phương thức “new”

static void Method(Token t) {

Console.WriteLine(t.Name()); } static void Main() {

IdentifierToken variable = new IdentifierToken("variable"); Method(variable);

}

Page 96: Chuong 2 - Ngon Ngu Lap Trinh CSharp

96

Phương thức “virtual”

virtual được dùng để định nghĩa phương thức hổ trợ đa hình

Đa hình nghĩa là có thể hiện thực 1 phương thức nhiều lần

Các lớp con tự lo hiện thực phiên bản của riêng mình của phương thức virtual bằng cách dùng từ khóa override

Page 97: Chuong 2 - Ngon Ngu Lap Trinh CSharp

97

Phương thức “virtual”

Virtual không thể được dùng với static và override

class Token {

⋮public virtual string Name() { ... }

}

Đây là phiên bản hiện thực đầu tiên của

phương thức Name()

Page 98: Chuong 2 - Ngon Ngu Lap Trinh CSharp

98

Phương thức “override”

Một phương thức override cung cấp một thực thi mới cho phương thức của lớp cơ sở. Phương thức lớp cơ sở nên khái báo là virtual

Accessibility level của phương thức cơ sở không thể bị thay đổi bởi phương thức override nó

Từ khóa new, static, virtual không thể được dùng cùng override

Page 99: Chuong 2 - Ngon Ngu Lap Trinh CSharp

99

Phương thức “override”

class IdentifierToken : Token {

⋮public override string Name() { ... }

}

Hiện thực khác của phương thức Name()

Page 100: Chuong 2 - Ngon Ngu Lap Trinh CSharp

100

Phương thức “override”

Phương thức private không thể là virtual hay override

Hai phương thức phải: cùng tên, cùng kiểu và số lượng tham số, cùng kiểu trả về

Hai phương thức phải cùng kiểu truy cập Chỉ có thể override phương thức virtual override ngầm hiểu là virtual có thể

override ở những phương thức con tiếp theo

Page 101: Chuong 2 - Ngon Ngu Lap Trinh CSharp

101

Đa hình

Để thực hiện tính đa hình chúng ta thực hiện các bước sau:• Phương thức trong lớp cha là phương thức

virtual, override hay abstract

• Phương thức trong lớp con là phương thức override

Page 102: Chuong 2 - Ngon Ngu Lap Trinh CSharp

102

Đa hình

Cú pháp

class ClassName1{

virtual public type Method(…){}

}

class ClassName2: ClassName1{

override public type Method(…){}

}

Page 103: Chuong 2 - Ngon Ngu Lap Trinh CSharp

103

Lớp sealed và abstract

Lớp trừu tượng• Lớp trừu tượng là lớp được khai báo để làm lớp cơ sở

cho lớp khác.

Chú ý:• Lớp trừu tượng không cho tạo đối tượng

• Khai báo phương thức trừu tượng chỉ trong lớp trừu tượng

• Thành viên trừu tượng không thể là static

• Phương thức của Lớp trừu tượng không thể private

• Phương thức trừu tượng không thể có modifier virtual

Page 104: Chuong 2 - Ngon Ngu Lap Trinh CSharp

104

Lớp sealed và abstract

using System;abstract class BaseClass{ public abstract void MethodA(); public void MethodB() { Console.WriteLine ("This is the non abstract method”); }}

class DerivedClass : BaseClass{ public override void MethodA() { Console.WriteLine ("This is the abstract method overriden in derived class"); }}

Page 105: Chuong 2 - Ngon Ngu Lap Trinh CSharp

105

Lớp sealed và abstract

class AbstractDemo{ public static void Main() { DerivedClass objDerived = new DerivedClass(); BaseClass objBase = objDerived; objBase.MethodA(); objDerived.MethodB(); }}

Page 106: Chuong 2 - Ngon Ngu Lap Trinh CSharp

106

Lớp sealed và abstract

Lớp sealed• Là một lớp không bao giờ dùng làm lớp cơ sở

• Lớp abstract không thể được dùng như là một lớp sealed

sealed class Point {     

public Point(int x, int y)     {         

X = x;         Y = y;     

}     public int X;     public int Y;

}

Page 107: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Interface

Page 108: Chuong 2 - Ngon Ngu Lap Trinh CSharp

108

Định nghĩa interface

Interface cho phép tách tên của phương thức ra khỏi thực thi của phương thức

Interface chỉ ra làm thế nào phương thức được dùng chứ không phải làm thế nào phương thức được thực thi

Page 109: Chuong 2 - Ngon Ngu Lap Trinh CSharp

109

Định nghĩa interface

Page 110: Chuong 2 - Ngon Ngu Lap Trinh CSharp

110

Định nghĩa interface

Interface cho phép chúng định nghĩa các hành vi hay khả năng và áp dụng cho các lớp

Interface là một lớp trừu tượng thuần túy

Chỉ chứa phương thức trừu tượng không có phần implement

Page 111: Chuong 2 - Ngon Ngu Lap Trinh CSharp

111

Định nghĩa interface

Cú pháp

Giới hạn• Không thể tạo instance của Interface • Không có field trong interface• Không có constructor và destructor• Không được viết access modifier• Không có kiểu lồng nhau• Không được thừa kế interface từ struct hay class

Interface có thể chứa các phương thức: Bao gồm property/indexer, event

interface Name { // Members}

Page 112: Chuong 2 - Ngon Ngu Lap Trinh CSharp

112

Cài đặt interface

Một lớp có thể cài đặt một hay nhiều interface Khi một lớp cài đặt interface phải cài đặt mọi

phương thức trong interface đó Các phương thức phải có modifier là public

Cú pháp class ClassName: InterfaceName{ // Members}

Page 113: Chuong 2 - Ngon Ngu Lap Trinh CSharp

113

Ví dụ

public interface IFile{ int delFile(); void disFile();}public class MyFile : IFile{ public int delFile() { System.Console.WriteLine ("DelFile Implementation!"); return(0); } public void disFile() { System.Console.WriteLine ("DisFile Implementation!"); }}

Page 114: Chuong 2 - Ngon Ngu Lap Trinh CSharp

114

Ví dụ

class InterfaceDemo{ public static void Main() { MyFile objMyFile = new MyFile(); objMyFile.disFile(); int retValue = objMyFile.delFile(); }}

Page 115: Chuong 2 - Ngon Ngu Lap Trinh CSharp

115

Phương thức “sealed”

Từ khóa sealed chỉ ra phương thức không được override trong lớp con của nó

class X{

public void method1(){ }virtual public void method2(){ }

}

class Y : X{

sealed override public void method2(){ }

}

class Z : Y{

override public void method2() { }}

Page 116: Chuong 2 - Ngon Ngu Lap Trinh CSharp

116

Đa thừa kế interface

C# cho phép hiện thực nhiều interface

public interface IFileTwo{ void applySecondInterface();}

Page 117: Chuong 2 - Ngon Ngu Lap Trinh CSharp

117

Đa thừa kế interface

public class MyFile : BaseforInterface, IFile, IFileTwo{ public int delFile() { System.Console.WriteLine ("DelFile Implementation!"); return(0); } public void disFile() { System.Console.WriteLine ("DisFile Implementation!"); } public void applySecondInterface() { System.Console.WriteLine ("ApplySecondInterface Implementation!"); }}

Page 118: Chuong 2 - Ngon Ngu Lap Trinh CSharp

118

Đa thừa kế interface

class MultipleInterfaces{ public static void Main() { MyFile objMyFile = new MyFile(); objMyFile.disFile(); int retValue = objMyFile.delFile(); objMyFile.open(); objMyFile.applySecondInterface(); }}

Page 119: Chuong 2 - Ngon Ngu Lap Trinh CSharp

119

Explicit Interface

Explicit Interface được dùng khi một phương thức cùng tên trong 2 interface

public interface IFile{ int delFile(); void disFile();}public interface IFileTwo{ void applySecondInterface(); void disFile();}

Page 120: Chuong 2 - Ngon Ngu Lap Trinh CSharp

120

Explicit Interface

public class MyFile : BaseforInterface, IFile, IFileTwo{... void IFile.disFile() { System.Console.WriteLine ("IFile Implementation of DisFile"); } void IFileTwo.disFile() { System.Console.WriteLine ("IFileTwo Implementation of DisFile"); }..}

Page 121: Chuong 2 - Ngon Ngu Lap Trinh CSharp

121

Thừa kế interface

Một interface có thể được tạo bằng cách tổ hợp nhiều interface khác

Cú pháp tương tự thừa kế trong class

interface InterfaceName1 : IterfaceName2, InterfaceName3, …{ //More operations can be added if necessary

}

Page 122: Chuong 2 - Ngon Ngu Lap Trinh CSharp

122

Abstract class vs. Interface

Abstract class Interface

Thành viên abstract cũng như không abstract

Tất cả thanh viên ngầm địn abstract

Định nghĩa lớp abstract có các thành viên abstract = định nghĩa interface

Lớp abstract có thể có các phần protected, phương thức…

Thành viên của interface là public không có implementation

Chỉ được thừa kế từ 1 lớp abstract

Một lớp có thể thừa kế từ 1 hay nhiều interfaces

Lớp Abstract có thể thêm nhiều chức năng mà không phá hủy các lớp con

Tạo thêm chức năng sẽ ảnh hưởng đến lớp con

Page 123: Chuong 2 - Ngon Ngu Lap Trinh CSharp

123

Interface chỉ ra tên của phương thức Virtual là implement đầu tiên của phương

thức Override là implement khác của phương thức Sealed là implement cuối cùng của phương

thức

Page 124: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Property – Mảng – Indexer

Page 125: Chuong 2 - Ngon Ngu Lap Trinh CSharp

125

So sánh Field và Phương thức

struct ScreenPosition {     

public ScreenPosition(int x, int y)     {         

X = rangeCheckedX(x);         Y = rangeCheckedY(y);     

}     public int X;     public int Y;     private static int rangeCheckedX(int x)     {         

if (x < 0 || x > 600)         { Console.WriteLine(“X”); }          return x;     

}     private static int rangeCheckedY(int y)     {         

if (y < 0 || y > 800)         { Console.WriteLine(“X”); }return y;      

} }

Bad idea

ScreenPosition topLeft = new ScreenPosition(65, 45); ⋮ int x = topLeft.X; topLeft.Y = 810; // !!!!!

Page 126: Chuong 2 - Ngon Ngu Lap Trinh CSharp

126

So sánh Field và Phương thức

Good ideal struct ScreenPosition {     

    ⋮public int GetX()     {         

return x;     }     public void SetX(int newX)     {        

x = rangeCheckedX(newX);     }     

    ⋮private static int rangeCheckedX(int x) { ... } private static int rangeCheckedY(int y) { ... } private int x, y;

}

int x = topLeft.GetX(); topLeft.SetX(x + 10); 

Dùng Field:

rõ ràng

Ngắn gọn

Dễ hiểu

Page 127: Chuong 2 - Ngon Ngu Lap Trinh CSharp

127

Định nghĩa property

Properties cho phép lập trình viên truy cập các field tự nhiên hơn thay cho việc sử dụng phương thức

Cú pháp <access_modifier> <return_type> <property_name>{

get{…}

set{…}

}

Page 128: Chuong 2 - Ngon Ngu Lap Trinh CSharp

128

Định nghĩa property

struct ScreenPosition{     

public ScreenPosition(int X, int Y)     {         

x = rangeCheckedX(X);         y = rangeCheckedY(Y);     

}     public int X     {         

get { return x; }         set { x = rangeCheckedX(value); }     

}     public int Y     {         

get { return y; }         set { y = rangeCheckedY(value); }    

 }     private static int rangeCheckedX(int x) { ... } private static int rangeCheckedY(int y) { ... } private int x, y;

}

ScreenPosition topLeft = new ScreenPosition(65, 45); ⋮ int x = topLeft.X; topLeft.Y = 810;

Page 129: Chuong 2 - Ngon Ngu Lap Trinh CSharp

129

Ví dụ property

public class Employee{ private String sName private String internal_sId public string sId { get { return internal_sId; } set { sId = internal_sId } }}

Page 130: Chuong 2 - Ngon Ngu Lap Trinh CSharp

130

Ví dụ property

. .

Employee emp = new Employee();emp.sId = ”S001”;Console.WriteLine("The student id is {0}”, emp.sId);

. . .

Page 131: Chuong 2 - Ngon Ngu Lap Trinh CSharp

131

Các loại property

Public Properties: Users có thể truy cập property không bị giới hạn nào

Private Properties: Users được truy cập trong lớp hay cấu trúc

Read / Write Property: Cung cấp cả read access và write access đến dữ liệu thành viên

Read - Only Property: Cung cấp read access đến dữ liệu thành viên

Write - Only Property: Cung cấp write access đến dữ liệu thành viên

Page 132: Chuong 2 - Ngon Ngu Lap Trinh CSharp

132

Ví dụ property

public class Employee{ private int empsalary = 15000; //Field public int EmpSalary //Property { get { return empsalary; } }}class EmployeeTest{

Page 133: Chuong 2 - Ngon Ngu Lap Trinh CSharp

133

Ví dụ property

static void Main() { Employee objEmployee = new Employee(); System.Console.WriteLine ("The salary of the Employee is {0}", objEmployee.EmpSalary); objEmployee.EmpSalary = 25000; //error }}

Page 134: Chuong 2 - Ngon Ngu Lap Trinh CSharp

134

Properties Vs Fields

Properties là logical fields

Properties là mở rộng của fields

Không giống fields, properties không có lưu trực tiếp dữ liệu

Page 135: Chuong 2 - Ngon Ngu Lap Trinh CSharp

135

Các giới hạn của Property

Properties không phải là field• Không thể khởi tạo property của struct thông qua set

accessorví dụ: ScreenPosition location;

location.X = 40;

• Không thể dùng property làm tham số ref, outví dụ: Method(ref topLeft.X); 

• Không thể khai báo nhiều property trên 1 câu lệnhví dụ: public int X, Y { get { ... } set { ... } }

• Không thể khai báo constant hay readonly propertyví dụ: const int X { get { ... } set { ... } }

Page 136: Chuong 2 - Ngon Ngu Lap Trinh CSharp

136

Các giới hạn của Property

Properties không phải là phương thức • Không thể viết code trước get, set

ví dụ: public int X  {       

Console.WriteLine("common code"); get { ... }      set { ... }

}

• Không thể khai báo property kiểu voidpublic void X { get { ... } set { ... } }

Page 137: Chuong 2 - Ngon Ngu Lap Trinh CSharp

137

Mảng

Mảng:• Tất cả các phần tử trong mảng cùng kiểu

• Các phần tử trong mảng được cấp phát liên tục

Phân loại• Mảng một chiều

• Mảng nhiều chiều

• Mảng Zich Zắc– Là mảng mà mỗi phần tử của nó là 1 mảng.– Mỗi phần tử của mảng có thể có kích thước khác nhau

• Mảng hỗn hợp

Page 138: Chuong 2 - Ngon Ngu Lap Trinh CSharp

138

Khai báo Mảng

Cú pháp: mảng 1 hay nhiều chiều

Trong đó• Dimension: số chiều được bao quanh trong

ngoặc vuông. Nếu có nhiều chiều toán tử dấu phẩy được dùng ngăn cách các chiều

Chú ý:• Không chỉ ra kích thước mảng khi khai báo• Đặt [ ] trước tên biến

DataType[dimension] ArrayName;

Page 139: Chuong 2 - Ngon Ngu Lap Trinh CSharp

139

Khai báo mảng

Mảng 1 chiều• type [] arrayName;

Mảng nhiều chiều• type [,] arrayName;• type [,,] arrayName;

Mảng zich zắc • type[][] arrayName;

Mảng hỗn hợp• type[][,,][,] arrayName;

Page 140: Chuong 2 - Ngon Ngu Lap Trinh CSharp

140

Tạo Mảng

Mảng là kiểu tham chiếu, một biến mảng tham chiếu đến một instance mảng trên heap.

Tạo mảng chúng ta dùng toán tử new Để lấy chiều dài mảng chúng ta dùng thuộc

tính Length

Page 141: Chuong 2 - Ngon Ngu Lap Trinh CSharp

141

Tạo Mảng

Kích thước mảng có thể được tính lúc runtime

int size = int.Parse(Console.ReadLine()); int[] pins = new int[size];

Page 142: Chuong 2 - Ngon Ngu Lap Trinh CSharp

142

Tạo Mảng

Mảng 1 chiều• arrayName=new type[num];• type [] arrayName = new type[num];

Mảng nhiều chiều• arrayName = new type[num1, num2];• type [,] arrayName = new type[num1, num2];

Mảng zich zắc • type[][] arrayName = new type[num][];

for (int x =0; x<arrayName.Length; x++)arrayName[x] = new type[x];

Page 143: Chuong 2 - Ngon Ngu Lap Trinh CSharp

143

Khởi tạo Mảng

Mảng 1 chiều• type [] arrayName = new type[num] {v1, v2, …, vnum};• type [] arrayName = new type[] {v1, v2, …, vnum};• type [] arrayName = {v1, v2, …, vnum};

Mảng nhiều chiều• type [,] arrayName = new type[num1, num2] {{x1,y1},…,{xnum1, xnum2}};• type [,] arrayName = new type[] {{x1,y1},…,{xnum1, xnum2}};• type [,] arrayName = {{x1,y1},…,{xnum1, xnum2}};

Mảng zich zắc • type[][] arrayName = new type[][]{new type{v1,…vn}, new type{v1, …, vm}};• type[][] arrayName = {new type{v1,…vn}, new type{v1, …, vm}};

Chú ý: Nếu khai báo và khởi tạo mảng riêng, chúng ta phải dùng toán tử new để khởi tạo mảng

Page 144: Chuong 2 - Ngon Ngu Lap Trinh CSharp

144

Mảng giá trị - Mảng tham chiếu

Mảng kiểu giá trị

Mảng đối tượng

Page 145: Chuong 2 - Ngon Ngu Lap Trinh CSharp

145

Truy cập mảng

Mảng 1 chiều• arrayName[x]

Mảng nhiều chiều• arrayName[x,y]

• arrayName[x,y,z]

Mảng zich zắc • arrayName[x][y]

Page 146: Chuong 2 - Ngon Ngu Lap Trinh CSharp

146

Ví dụ: mảng

Ví dụint [] arr = new int[10];for (int i=0; i<arr.Length; i++)

arr[i] = i;

Chúng ta có thể dùng vòng lặp foreach duyệt qua mảng int [] arr = new int[10];for (int i=0; i<arr.Length; i++)

arr[i] = i;foreach (int elem in arr)

Console.write(“{0} ”, elem);

Page 147: Chuong 2 - Ngon Ngu Lap Trinh CSharp

147

Ví dụ: mảng

Page 148: Chuong 2 - Ngon Ngu Lap Trinh CSharp

148

Ví dụ: mảng

Mảng nhiều chiềuint [,] arr1 = new int[4,5];int [,,]arr2 = new int[5,6,4];

Zich zacint[][] arr;arr = new int[5][];arr[0] = new int[6];arr[1] = new int[5];arr[2] = new int[3];arr[3] = new int[7];arr[4] = new int[5];

Page 149: Chuong 2 - Ngon Ngu Lap Trinh CSharp

149

Sao chép Mảng

Mảng là kiểu tham chiếu. Khi sao chép 1 biến mảng chúng ta sẽ có 2 tham chiếu đến cùng 1 instance mảng

Nếu muốn sao chép các instance mà mảng đang tham chiếu đến chúng ta thực hiện 2 bước• Tạo một instance mảng mới

• Thiết lập các giá trị trong mảng mới như mảng gốc

Page 150: Chuong 2 - Ngon Ngu Lap Trinh CSharp

150

Sao chép Mảng

Sao chép mảng là shallow copy chứ không phải deep copy

Triangle[] triangles = new Triangle[4];

Page 151: Chuong 2 - Ngon Ngu Lap Trinh CSharp

151

Sao chép Mảng

Triangle[] triangles = new Triangle[4]; for (int i = 0; i != triangles.Length; i++) {     

triangles[i] = new Triangle(); }

Page 152: Chuong 2 - Ngon Ngu Lap Trinh CSharp

152

Sao chép Mảng

Triangle[] copy = new Triangle[triangles.Length]; for (int i = 0; i != copy.Length; i++) {     

copy[i] = triangles[i]; }

Page 153: Chuong 2 - Ngon Ngu Lap Trinh CSharp

153

System.Array {1}

Mảng thật ra là đối tượng, dẫn xuất từ lớp cơ sở trừu tượng System.Array

Chúng ta có thể dùng bất kỳ phương thức và thuộc tính nào System.Array có trên mảng

Thành viên Loại thành viên Ý nghĩa

Rank Readonly instance property Trả về số chiều của mảng

GetLength Instance method Trả về số phần tử trong chiều được chỉ định của mảng

Length Readonly instance property Trả về tổng số phần tử của mảng

GetLowerBound Instance method Trả về cận dưới của một chiều cho trước. Phần lớn là 0

GetUpperBound Instance method Trả về cận trên của một chiều cho trước. Phần lớn là số phần tử của chiều đó trừ 1

IsReadOnly Readonly instance property Cho biết mảng chỉ đọc hay không. Luôn luôn là false

IsSynchronized Readonly instance property Cho biết mảng truy cập an toàn thread hay không. Luôn luôn là false

SyncRoot Readonly instance property Trả về một đối tượng cho phép truy cập đồng bộ đến mảng. Luôn luôn trả về chính mảng đang dùng

IsFixedSize Readonly instance property Cho biết mảng có kích thước cố định hay không. Luôn luôn là true

GetValue Instance method Trả về giá trị của phần tử

Page 154: Chuong 2 - Ngon Ngu Lap Trinh CSharp

154

System.Array {2}

Thành viên Loại thành viên Ý nghĩa

SetValue Instance method Thiết lập giá tri của phần tử

GetEnumerator Instance method Trả về một IEnumerator. Cho phép dùng câu lệnh foreach

Sort Static method Sắp xếp các phần tử trong 1 mảng, trong 2 mảng hay trong một vùng của 1 mảng. Kiểu của các phần từ phải implement IComparer interface hay phải truyền một đối tượng mà kiểu implement interface IComparer

BinarySearch Static method Tìm kiếm theo thuật toán tìm kiếm nhị phân. Phương thức này giả sử mảng đã được sắp xếp. Kiểu của các phần từ phải implement IComparer interface. Chúng ta thường dùng phương thức Sort trước khi gọi BinarySearch.

IndexOf Static method Trả về vị trí xuất hiện đầu tiên của một giá trị trong mảng 1 chiều hay trong một phần của mảng

LastIndexOf Static method Trả về vị trí xuất hiện cuối cùng của một giá trị trong mảng 1 chiều hay trong một phần của mảng

Reverse Static method Đảo thứ tự các phần tử trong mảng 1 chiều hay trong một phần của mảng

Clone Instance method Tạo một mảng mới là bản sao của mảng gốc

CopyTo Instance method Sao chép các phần từ từ một mảng sang một mảng khác

Copy Static method Sao chép một phần các phần từ sang mảng khác, thực hiện bất kỳ yêu cầu casting nào

Clear Static method Thiệt lập một vùng các phần tử thành 0 hay null

CreateInstance Static method Tạo một instance của mảng. Phương thức hiếm dùng này cho phép định nghĩa mảng động lúc thời gian chay với bất kỳ kiểu, vùng, cận

Initialize Instance method Gọi constructor mặc nhiên của các phần tử kiều giá trị (phương thức này không thực hiện nếu các phần tử là kiễu tham chiếu)

Page 155: Chuong 2 - Ngon Ngu Lap Trinh CSharp

155

Định nghĩa Indexer

Indexer cho phép coi các đối tượng như là các mảng

Cú phápclass MyClass {     

public <type> this [int idx]     {        

get { // Return giá trị}         set  { // thiết lập giá trị mong muốn}

} }

Page 156: Chuong 2 - Ngon Ngu Lap Trinh CSharp

156

Ví dụ indexer

class IndexerExample{ public string[] stringList =new string[10]; public string this[int index] { get { return stringList[index]; }

set { stringList[index] = value.ToString(); } }}

Page 157: Chuong 2 - Ngon Ngu Lap Trinh CSharp

157

Ví dụ indexer

class Test{ static void Main() { IndexerExample indexTest = new IndexerExample(); indexTest.stringList[1]="Sam"; indexTest[2]="Tom"; System.Console.WriteLine("indexTest[1] is {0}\nindexTest[2] is {1}", indexTest[1], indexTest[2]);}}

Page 158: Chuong 2 - Ngon Ngu Lap Trinh CSharp

158

So sánh Indexer với Phương thức

Indexer phải có ít nhất 1 tham sốpublic bool this [ ] { ... } 

Không thể thêm code ngoài get/set trong indexerpublic bool this [ int index ] {     

boundsCheck(index); get { ... }     set { ... }

} Indexer không thể có kiểu trả về void

public void this [ int index ] { ... }

Page 159: Chuong 2 - Ngon Ngu Lap Trinh CSharp

159

So sánh Indexer với Array

Indexer không trỏ đến vị trí bộ nhớ

Indexer có thể có chỉ mục không là số nguyênpublic int this [ string name ] { ... } // ok

Indexer có thể được overloadpublic Name this [ PhoneNumber number ] { ... } public PhoneNumber this [ Name name ] { ... } // ok

Indexer không thể dùng như tham số ref, outIntBits bits;  Method(ref bits[1]);  // error

Page 160: Chuong 2 - Ngon Ngu Lap Trinh CSharp

160

Ví dụ indexer

using System.Collections;class StrIndex{ public Hashtable studentList = new Hashtable(); public int this[string name] { get { return (int) studentList[name]; } set { studentList[name] = value; } }}

Page 161: Chuong 2 - Ngon Ngu Lap Trinh CSharp

161

Ví dụ indexer

class Test{ static void Main() { StrIndex objIndex = new StrIndex(); objIndex ["Sam"] = 232676; objIndex ["Tom"] = 455464; System.Console.WriteLine ("Phone number of Sam is {0} and Phone number of Tom is {1}", objIndex ["Sam"], objIndex["Tom"]); }}

Page 162: Chuong 2 - Ngon Ngu Lap Trinh CSharp

162

Ví dụ indexer

using System.Collections;class IndexerExample{ public string[] stringList = new string[10]; public string this[int index] { get { return stringList[index]; } set { stringList[index] = value.ToString(); } } public Hashtable studentList = new Hashtable();

Page 163: Chuong 2 - Ngon Ngu Lap Trinh CSharp

163

Ví dụ indexer

public int this[string number] { get { return (int) studentList [number]; } set { studentList [number] = value; } }

}

Page 164: Chuong 2 - Ngon Ngu Lap Trinh CSharp

164

Ví dụ indexer

class Test{ static void Main() { IndexerExample indexTest = new IndexerExample(); indexTest.stringList[1] = "Sam"; indexTest[2] = "Tom"; indexTest ["Sam"] = 232; indexTest ["Tom"] = 455; }}

Page 165: Chuong 2 - Ngon Ngu Lap Trinh CSharp

165

Indexer có nhiều tham số

Nhiều tham số: indexer được truy cập như mảng nhiều chiều

...class TestMultip{ public int this[int firstP, int secondP] { //Get and Set Accessors appear here }}. . .

Page 166: Chuong 2 - Ngon Ngu Lap Trinh CSharp

166

Indexer có nhiều tham số

…{ void static Main() {

TestMultip myTest = new TestMultip();int I = myTest[1,1];

}}

Page 167: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Struct - Enum

Page 168: Chuong 2 - Ngon Ngu Lap Trinh CSharp

168

Định nghĩa Struct

Struct là một kiểu giá trị Có thể có phương thức bên trong Không thể thừa kế

Cú pháp [attributes] [modifiers] struct <structName> [: interfaces] {     

[struct-body] }[;]

Page 169: Chuong 2 - Ngon Ngu Lap Trinh CSharp

169

Ví dụ Struct

RGB rgb; rgb.Red = 0xFF; rgb.Green = 0xFF; rgb.Blue = 0xFF;

struct RGB {     

public int Red;     public int Green;  

public int Blue; } 

Page 170: Chuong 2 - Ngon Ngu Lap Trinh CSharp

170

Ví dụ Struct

…struct structEx{ public int structDataMember; public void structMethod1() {

//structMethod1 Implementation }}…

Page 171: Chuong 2 - Ngon Ngu Lap Trinh CSharp

171

Sử dụng Structs

Không phải khởi tạo struct bằng từ khóa new

Các field không được khởi tạo cho đến khi:• Dùng từ khóa new• Khởi tạo tường minh các thành viên

Các thành viên Struct có thể có các constructor, constant, field, method, property, indexer, operator, và các kiểu lồng nhau

Một giới hạn quan trọng của struct: không thể tạo constructor không tham số

Page 172: Chuong 2 - Ngon Ngu Lap Trinh CSharp

172

Kiểu enum

Mặc nhiên, phần tử đầu tiên trong enum được gán giá trị 0 và các phần tử sau có giá trị tăng dần lên 1

Giá trị mặc nhiên có thể thay đổi

public enum WeekDays{

Monday=1,Tuesday=2,Wednesday=3,Thursday=4,Friday=5

}

Page 173: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Collections

Page 174: Chuong 2 - Ngon Ngu Lap Trinh CSharp

174

Các lớp collection

Mảng là một cách để tập hợp các phần tử cùng kiểu

Các lớp collection tập hợp các phần tử của nó như các object. Kiểu của các phần tử trong lớp collection luôn luôn là object

System.Collections • Cung cấp vài lớp để tập hợp các phần tử

Page 175: Chuong 2 - Ngon Ngu Lap Trinh CSharp

175

Mảng giá trị - Mảng tham chiếu

Mảng kiểu giá trị

Mảng đối tượng

Khi chèn 1 giá trị vào collection box

Khi remove 1 giá trị từ collection unbox

Page 176: Chuong 2 - Ngon Ngu Lap Trinh CSharp

176

ArrayList

ArrayList là một lớp hữu dụng cho việc bố trí các phần tử trong mảng

Những giới hạn của mảng• Thay đổi lại kích thước mảng

• Xóa một phần tử khỏi mảng

• Thêm một phần tử vào mảng

Page 177: Chuong 2 - Ngon Ngu Lap Trinh CSharp

177

ArrayList

ArrayList khắc phục giới hạn của mảng• Xóa một phần tử khỏi ArrayList bằng phương

thức Remove

• Thêm một phần tử vào cuối ArrayList bằng phương thức Add (resize khi cần thiết)

• Thêm một phần tử vào giữa ArrayList bằng phương thức Insert (resize khi cần thiết)

Page 178: Chuong 2 - Ngon Ngu Lap Trinh CSharp

178

ArrayList

Properties Ý nghĩa

Capacity

Count

IsFixedSize

IsReadOnly

IsSynchronize

Item

SyncRoot

Page 179: Chuong 2 - Ngon Ngu Lap Trinh CSharp

179

ArrayList

Methods Ý nghĩa

Add

AddRange

Clear

Contains

CopyTo

FixedSize

IndexOf

LastIndexOf

Insert

InsertAt

Remove

RemoveAt

Sort

BinarySort

Reverse

Page 180: Chuong 2 - Ngon Ngu Lap Trinh CSharp

180

Queue

Queue hiện thực collection FIFO• Thêm vào queue: Enqueue

• Lấy ra khỏi queue: Dequeue

Page 181: Chuong 2 - Ngon Ngu Lap Trinh CSharp

181

Stack

Stack hiện thực collection LIFO• Thêm vào stack: Push

• Lấy ra khỏi stack: Pop

Page 182: Chuong 2 - Ngon Ngu Lap Trinh CSharp

182

So sánh Mảng và Collection

Mảng có khai báo kiểu của phần tử Mảng có kích thước cố định và không tự tăng

kích thước Mảng là CTDL cho phép read/write. Các lớp

collection có thể được dùng theo cách readonly

Page 183: Chuong 2 - Ngon Ngu Lap Trinh CSharp

183

Tự Tạo collection

Iteration• foreach hoạt động như thế nào

• Làm thế nào dùng foreach với lớp của chúng ta

Page 184: Chuong 2 - Ngon Ngu Lap Trinh CSharp

184

Tự Tạo collection

class MyCollectionClass : IEnumerable{ ... }

foreach (string s in myCollection){

Console.WriteLine("String is {0}", s);}

IEnumerator ie = (IEnumerable) myCollection;IEnumerator e = ie. GetEnumerator(); while (e.MoveNext()){

string s = (string) e.Current; Console.WriteLine("String is {0}", s);

}

Page 185: Chuong 2 - Ngon Ngu Lap Trinh CSharp

185

Tự Tạo collection

public interface IEnumerable{

IEnumerator GetEnumerator();}

public interface IEnumerator{

object Current { get; }bool MoveNext();void Reset();

}

Page 186: Chuong 2 - Ngon Ngu Lap Trinh CSharp

186

Tự Tạo collection

class MyCollectionClass : IEnumerable

{CollectionPart[] _parts;......public IEnumerator GetEnumerator(){}

}

Page 187: Chuong 2 - Ngon Ngu Lap Trinh CSharp

187

Tự Tạo collection

class MyCollectionClass : IEnumerable

{CollectionPart[] _parts;......public IEnumerator GetEnumerator(){

return _parts.GetEnumerator()

}}

Vì _parts là System.Array, là một kiểu liệt kê nên nó có phương thức GetEumerator() trả về IEnumerator

Page 188: Chuong 2 - Ngon Ngu Lap Trinh CSharp

188

Tự Tạo collection

Giải pháp : tiếp cận dựa trên mẫu• Trình biên dịch C# compiler tìm kiếm:

– GetEnumerator() trên collection– bool MoveNext() trên kiểu enumerator– Current trên kiểu enumerator

Page 189: Chuong 2 - Ngon Ngu Lap Trinh CSharp

189

Tự Tạo collection

Foreach làm cho việc liệt kê dễ dàng• Nhưng enumerator khó viết

Page 190: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Exception

Page 191: Chuong 2 - Ngon Ngu Lap Trinh CSharp

191

Errors

Các lớp .NET Framework dùng các exception để thông báo lỗi.

Nếu chúng ta muốn lập trình trong .NET chúng ta phải biết exception

Exception là giải pháp hướng đối tượng cho bắt lỗi

Page 192: Chuong 2 - Ngon Ngu Lap Trinh CSharp

192

Try code và Catch exception

Ý tưởng chính của bắt ngoại lệ : tách code hiện thực luồng chính của chương trình với code bắt bắt lỗi• Dễ hiểu

Hai bước• Viết code trong khối try

• Viết một hay nhiều khối catch ngay sau khối try

Page 193: Chuong 2 - Ngon Ngu Lap Trinh CSharp

193

Try code và Catch exception

try {     

int lhs = System.Int32.Parse(lhsOperand.Text);     int rhs = System.Int32.Parse(rhsOperand.Text);     int answer = doCalculation(lhs, rhs);     result.Text = answer.ToString();

} catch (System.FormatException caught) {     

// Handle the exception      ⋮}

Page 194: Chuong 2 - Ngon Ngu Lap Trinh CSharp

194

Nhiều catch

Những lỗi khác nhau ném các loại exception khác nhau

try {     

int lhs = System.Int32.Parse(lhsOperand.Text);     int rhs = System.Int32.Parse(rhsOperand.Text);     int answer = doCalculation(lhs, rhs);     result.Text = answer.ToString();

} catch (System.FormatException caught) {     //... } catch (System.DivideByZeroException caught) {     //... }

Page 195: Chuong 2 - Ngon Ngu Lap Trinh CSharp

195

Viết catch tổng quát

Nếu chúng ta không muốn viết từng loại catch cho từng exception khác nhau chúng ta có thể viết một catch bắt mọi exception

try {     int lhs = System.Int32.Parse(lhsOperand.Text);     int rhs = System.Int32.Parse(rhsOperand.Text);     int answer = doCalculation(lhs, rhs);     result.Text = answer.ToString();

} catch (System.Exception caught) // this is the general catch handler {     //... }

Page 196: Chuong 2 - Ngon Ngu Lap Trinh CSharp

196

Viết catch tổng quát

Chú ý• Nếu có nhiều catch phù hợp với lỗi thì catch

nào gần try nhất sẽ được sử dụng

• Không nên đặt catch tổng quát lên trên những catch khác

Page 197: Chuong 2 - Ngon Ngu Lap Trinh CSharp

197

Kiểm tra tràn số học

Câu lệnh checked: tất cả phép toán số học trên số nguyên được kiểm tra tràn số - OverflowException

int number = System.Int32.MaxValue; checked {     

int willThrow = number++;     Console.WriteLine("this won’t be reached");

}

int number = System.Int32.MaxValue; unchecked {     

int willThrow = number++;     Console.WriteLine("this won’t be reached");

}

Page 198: Chuong 2 - Ngon Ngu Lap Trinh CSharp

198

Biểu thức checked

Chúng ta cũng có thể dùng từ khóa checked và unchecked để kiểm tra tràn số học trên biểu thức

int wontThrow = unchecked(System.Int32.MaxValue + 1); int willThrow = checked(System.Int32.MaxValue + 1);

Page 199: Chuong 2 - Ngon Ngu Lap Trinh CSharp

199

Ném ngoại lệ

Câu lệnh ném ngoại lệ gồm 2 phần• Từ khóa throw

• Đối tượng được ném

throw new System.ArgumentOutOfRangeException("Bad month");

Page 200: Chuong 2 - Ngon Ngu Lap Trinh CSharp

200

Khối finally

Khối finally đảm bảo những câu lệnh trong khối đó luôn luôn chạy cho dù có exception xảy ra hay không

Khối finally được đặt ngay sau khối try hay ngay sau khối catch

Page 201: Chuong 2 - Ngon Ngu Lap Trinh CSharp

201

Khối finally

TextReader reader = null;  try {     

reader = src.OpenText();     string line;     while ((line = reader.ReadLine()) != null)     {         

source.Text += line + "\n";     }

} finally {     

if (reader != null)     {         

reader.Close();     }

}

Page 202: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Delegates

Page 203: Chuong 2 - Ngon Ngu Lap Trinh CSharp

Events