chuong 2 - ngon ngu lap trinh csharp

Post on 16-Apr-2015

43 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

GV: Tôn Quang Toại

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

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!"); }

}

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]); }

} }

5

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

using System; public class Hello3 {

public static int Main() {

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

} }

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ố

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

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

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

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 “.”

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

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;

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

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;

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();

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

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()

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;

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

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)

Hệ thống kiểu .NET

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

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ỳ

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);

};

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

26

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

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, …

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

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

30

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

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ị

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

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ế.

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

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

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

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

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

39

Kiểu ký tự

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

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

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

char 16

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• +, []

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

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

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

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

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

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");

        }

     }

}

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

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> 

}

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>;

50

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

Giống C/C++

//

/**/

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

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 )

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);

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);

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]}

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();

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

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

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;

}

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;

}

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;

}

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;

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

}

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);

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

}

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

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]

}[;]

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;

}

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

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

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

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)

{

}

}

73

Phương thức

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

{

Method(ref type variableName)

{

}

}

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);

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;

}

}

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);

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ố.

78

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

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

• Toán tử 2 ngôi

+ - ! ~

++ -- true false

+ - * / % &

| ^ << >> == !=

> < >= <=

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])

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()

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(…)

{….}

}

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(…)

{….}

}

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>(…);

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

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(…)

{

}

}

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;

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

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;}

}

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;}

}

Thừa kế

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{

…}

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(…)

{….}

}

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() { ... }

}

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() { ... }

}

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);

}

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

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()

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

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()

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

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

102

Đa hình

Cú pháp

class ClassName1{

virtual public type Method(…){}

}

class ClassName2: ClassName1{

override public type Method(…){}

}

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

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"); }}

105

Lớp sealed và abstract

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

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;

}

Interface

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

109

Định nghĩa interface

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

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}

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}

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!"); }}

114

Ví dụ

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

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() { }}

116

Đa thừa kế interface

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

public interface IFileTwo{ void applySecondInterface();}

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!"); }}

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(); }}

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();}

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"); }..}

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

}

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

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

Property – Mảng – Indexer

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; // !!!!!

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

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{…}

}

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;

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 } }}

130

Ví dụ property

. .

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

. . .

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

132

Ví dụ property

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

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 }}

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

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 { ... } }

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 { ... } }

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

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;

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;

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

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];

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];

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

144

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

Mảng kiểu giá trị

Mảng đối tượng

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]

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);

147

Ví dụ: mảng

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];

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

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];

151

Sao chép Mảng

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

triangles[i] = new Triangle(); }

152

Sao chép Mảng

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

copy[i] = triangles[i]; }

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ử

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)

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}

} }

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(); } }}

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]);}}

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 ] { ... }

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

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; } }}

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"]); }}

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();

163

Ví dụ indexer

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

}

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; }}

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 }}. . .

166

Indexer có nhiều tham số

…{ void static Main() {

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

}}

Struct - Enum

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] }[;]

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; } 

170

Ví dụ Struct

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

//structMethod1 Implementation }}…

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ố

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

}

Collections

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ử

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

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

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)

178

ArrayList

Properties Ý nghĩa

Capacity

Count

IsFixedSize

IsReadOnly

IsSynchronize

Item

SyncRoot

179

ArrayList

Methods Ý nghĩa

Add

AddRange

Clear

Contains

CopyTo

FixedSize

IndexOf

LastIndexOf

Insert

InsertAt

Remove

RemoveAt

Sort

BinarySort

Reverse

180

Queue

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

• Lấy ra khỏi queue: Dequeue

181

Stack

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

• Lấy ra khỏi stack: Pop

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

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

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);

}

185

Tự Tạo collection

public interface IEnumerable{

IEnumerator GetEnumerator();}

public interface IEnumerator{

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

}

186

Tự Tạo collection

class MyCollectionClass : IEnumerable

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

}

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

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

189

Tự Tạo collection

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

Exception

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

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

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      ⋮}

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) {     //... }

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 {     //... }

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

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");

}

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);

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");

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

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();     }

}

Delegates

Events

top related