Những chủ đề tiến bộ trong C#
Delegate – Phần 1
Delegate có thể được xem như là kiểu đối tượng mới trong C#, mà có môt s
điểm quen thuộc với lớp.chúng tồn tại trong tình hung mà ta muốn truyền
phương thức xung quanh những phương thức khác.để minh hoạ ta xem ng
mã sau:
int i = int.Parse("99");
Chúng ta quen vi việc truyền dữ liệu đến một phương thức như thông
số,vì vy ý tường truyền phương thức như tng snghe vẻ i lđối
với chúng ta.tuy nhiên trường hợp ta 1 phương thức mà làm 1 điều
đó, nhiều hơn xử dliu, phương thức đó thể cần m điều gì đó
liên quan đến việc thực thi phương thức khác.phức tạp hơn, bạn kng
biết vào lúc nào tphương thức thứ hai sẽ được biên dịch. thông tin đó ch
biết vào lúc chy , và chính do đó phương thức 2 sẽ cần truyền vào
như là thông số cho phương thức đầu tiên.điều này nghe v hơi k
hiểu,nhưng nó sẽ được làm rõ hơn trong 1 vài ví dụ sau:
Luồng bắt đầu: C# có thể bảo máy tính bắt đầu một chuỗi thực thi mới song
song vi việc thực thi đương thời.1 chuỗi liên tiếp này gọi là luồng,và việc
bắt đầu này được làm bng cách dùng phương thức, Start() trên 1 thhiện
của lớp cơ sở.System.Threading.Thread. ( chi tiết n về luồng chương
5).khi chương trình bắt đầu chạy,nơi bt đầu main(). tương tự như vậy
khi bn muốn máy tính chạy một chuỗi thực thi thì bn phải báo cho y
tính biết bắt đầu chạy là ở đâu. bạn phải cung cấp cho nó chi tiết của phương
thức mà việc thực thi thể bắt đầu.-nói cách khác , phương thức
Thread.Start() phi lấy 1 tng sđịnh nghĩa phương thức được thi hành
bởi luồng.
Lớp thư viện chung . khi 1 nhim vụ chứa đựng nhiệm vụ con mà của
các nhim vụ con y được viết trong các thư viện chỉ sử dụng tviện
mới biết làm gì.d, chúng ta muốn viết một lớp chứa một mảng đối
tuợng và sắp ng dần. 1 phần ng vic được lp lại là lấy 2 đối tượng
trong lớp so sánh với nhau để xem đối tượng nào đứng truớc.nếu ta muốn
lp có khả năng sắp xếp bất kì đối tượng nào, không cách nào có thlàm
được việc so sánh trên .client dùng mảng đối tượng của ta sẽ bảo cho ta
biết cách so nh cthể đối tượng mà mun sắp xếp.nói cách khác , mã
client s phải truyền cho lớp của ta phương thức thích hợp mà thđược
gọi, để làm việc so nh.
Nguyên tắc chung là: của ta sẽ cần thông báo cho thời gian chạy .NET
biết phương thức nào xlí tình huống nào.
thế chúng ta phải thiết lập nhng nguyên tc mà đôi lúc , những phương
thức cần lấy chi tiết của phương thức khác như thông số.kế tiếp chúng ta
sminh họa cách làm điều đó.cách đơn giản nhất là truyền tên của phương
thức như thông số.giả sử chúng ta muốn bắt đầu một luồng mới, và chúng
ta phương thức được gọi là entrypoint(), mà ta muốn lung bắt đầu chạy
từ đó:
void EntryPoint()
{
// làm những gì luồng mi cần làm
}
Có thể chúng ta bắt đầu luồng mới với một đoạn mã :
Thread NewThread = new Thread();
Thread.Start(EntryPoint); // sai
Thật sđây cách đơn giản nhất. trong một vài ngôn ngdùng ch này
như c và c++ ( trong c và c++ thông sentrypoint là con trhàm)
Không may, cách thực thi trực tiếp này y ra một số vn đề về an toàn
kiểu.nhớ rằng ta đang lập trình hướng đôí tượng, phương thức hiếm khi nào
tồn tại độc lập , tng là phải kết hợp với phương thức khác trưóc khi
được gi.vì vy .NET không cho m điều này.thay vào đó nếu ta muốn
truyền phương thức ta phải gói chi tiết ca phương thức trong một loại đối
tượng mới 1 delegate. delegate đơn giản là một kiu đối tượng đặc biệt-
đặc bit ở chổ ,trong khi tất cả đối tượng chúng ta định nghĩa trước đây chứa
đựng dữ liệu , thì delegate chứa đựng chi tiết của phương thức.
Dùng delegate trong C#
Đầu tiên ta phải định nghĩa delegate mà ta muốn dùng ,nghĩa là bảo cho
trình bn dịch biết loại pơng thức mà delegate s trình y.sau đó ta tạo
ra các thể hiện của delegate.
Cú pháp
delegate void VoidOperation(uint x);
Ta ch định mỗi thể hiện của delegate thể giữ một tham chiếu đến 1
phương thức mà chứa một thông số uint và trả vầ kiểu void.
d khác : nếu bạn muốn định nghĩa 1 delegate gọi là twolongsOp
trình bày 1 hàm có 2 thông số kiểu long và trả về kiểu double. ta có thể viết :
delegate double TwoLongsOp(long first, long second);
Hay 1 delegate trình y phương thức không nhận thông s và trvề kiểu
string
delegate string GetAString();
pháp cũng giống như pơng thức , ngoại trừ việc không phần thân
của phương thức,và bắt đầu với delegate.ta cũng thể áp dụng c cách
thức truy nhập thông thường trên một định nghĩa delegate -
public,private,protected ...
public delegate string GetAString();
Mỗi lần ta định nghĩa một delegate chúng ta thể tạo ra một thể hiện của
nó mà ta có thể dùng đề lưu trữ các chi tiết của 1 pong thức cụ thể.
Lưu ý : với lớp ta 2 thuật ngữ riêng biệt : lớp để chỉ định nghĩa chung ,
đối tượng để chỉ một thể hiện của 1 lớp, tuy nhiên đối với delegate ta chỉ có
một thuật ngữ là '1 delegate' khi tạo ra một thể hiện của delegate ta cũng gọi
nó là delegate. vì vy cần xem t ngữ cnh để phân biệt.
Đoạn mã sau minh hoạ cho 1 delegate:
private delegate string GetAString();
static void Main(string[] args)
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);