Tản mạn C#: Hello World
Hầu hết mọi thứ trong C# là đối tượng (object). Do đó, khi động đến C#, ta không thể tránh khỏi làm việc với class. Khái niệm class trong C# vay mượn khá nhiều từ C++. Tuy vậy, C# không mù quáng mà sao chép y nguyên. Những cú pháp rườm rà thường gây ra lỗi trong C++ đã được C# chắt lọc và đơn giản hóa nhằm tăng hiệu quả khi viết code. Nếu so sánh đoạn code định nghĩa class trong C# và C++, ta thấy C# gọn nhẹ hơn, không chứa nhiều chi tiết lặt vặt như C++. Đơn cử là dấu chấm phẩy sau định nghĩa class trong C++ mà tôi rất hay quên. Trong C#, tôi không phải lo về cái dấu nhỏ xíu đó.
Tất cả code C# đều phải nằm trong class
hoặc struct
. Điều này không bắt buộc trong C++. Cách thức tạo class
hoặc struct
trong C# rất giống C++.
1
2
3
4
5
6
7
8
9
class Program
{
...
}
struct Program
{
...
}
Khi tạo project mới trong Visual Studio, file chứa code C# sẽ có phần mở rộng là .cs và có tên trùng với tên class nó chứa. Điều này không bắt buộc, tên file có thể khác tên class và một file có thể chứa nhiều class. Đặc biệt, một class có thể tách ra và nằm ở nhiều file bằng cách dùng từ khóa partial
. Thông thường, để dễ quản lý, ta chỉ cần tạo một class hoặc struct nằm trong một file và đặt tên file trùng với tên class hoặc struct đó.
Giống như C++, C# bắt đầu với hàm Main
, hay nói đúng hơn là method Main
vì hàm nằm trong class được gọi là method. Chữ M của Main
được viết hoa, khác với main
trong C++.
1
2
3
4
5
6
7
public class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine("Hello World");
}
}
Từ khóa public
cho biết rằng method Main
có thể được truy xuất từ bên ngoài phạm vi class chứa nó. Tuy vậy, khi bỏ public
thì chương trình vẫn hoạt động bình thường. Có hay không từ khóa public
đều không quan trọng với Main
, đằng nào nó cũng chạy.
Từ khóa static
có nghĩa là Main
thuộc class Program
chứ không phải thuộc một thực thể (instance) của nó. Do vậy, để gọi Main
thì ta không cần tạo một object của class Program
. Từ khóa static
đối với Main
là bắt buộc bởi vì ngay lúc chạy chương trình, chưa có object nào được tạo ra trong bộ nhớ. Do đó, Main
phải được truy xuất không qua một object nào cả.
Từ khóa void
chỉ ra rằng Main
không trả về bất kì giá trị nào. Tuy nhiên, nó có thể trả về giá trị kiểu int
nếu muốn (giống C++).
Phần tham số của Main
nhận một mảng kiểu string
để chứa các thông số dòng lệnh khi chạy chương trình. Phần tham số này không bắt buộc, ta có thể bỏ nếu không dùng đến.
Phần thân của Main
nằm giữa hai dấu ngoặc nhọn giống C++. Tương tự, câu lệnh C# cũng kết thúc bằng dấu chấm phẩy. Phần thân của Main
rất đơn giản, nó chỉ gồm câu lệnh xuất ra màn hình chữ “Hello world”. Điều cần lưu ý ở đây là chuỗi trong C# phải nằm trên cùng một dòng, nếu muốn nối nhiều chuỗi riêng biệt với nhau thì có thể dùng toán tử +
quen thuộc.
Chương trình của ta không thực hiện chức năng gì phức tạp, nó gọi duy nhất một method tên System.Console.WriteLine()
. Trong đó, System
là tên của namespace chứa class Console
và class Console
chứa method WriteLine()
. Nếu tra cứu trong MSDN thì ta thấy WriteLine có khá nhiều phiên bản khác nhau, ta gọi chúng là các “quá tải” (overload). Quan sát kỹ, ta thấy WriteLine()
được khai báo static
tương tự Main
. Điều này nghĩa là ta chỉ có thể gọi method thông qua tên class chứa nó, trong trường hợp này là class Console
, và ta phân cách tên class và tên method bằng dấu chấm (thay vì phải dùng dấu ::
như trong C++). Chuyển qua trang thông tin về class Console trên MSDN, ta phát hiện ra class Console
nằm trong một file DLL tên là mscorlib.dll
. Đây là file assembly chứa code cho class Console
. File mscorlib.dll
có vai trò rất quan trọng trong .NET vì nó chứa tất cả các class và struct căn bản mà hầu hết các chương trình .NET đều sử dụng.
Khi biên dịch chương trình C++, ta thường sử dụng chỉ thị #include
ở đầu file để tham chiếu đến các file header. File header cung cấp prototype cho các hàm trong file. Trình biên dịch C# không cần file header. Trong quá trình biên dịch, trình biên dịch C# truy cập trực tiếp file mscorlib.dll
và lấy thông tin cần thiết từ metadata trong đó. Tiếp theo, trình biên dịch xác định xem câu lệnh gọi hàm WriteLine()
có hợp lệ không, nếu có thì trình biên dịch sẽ thiết lập một tham chiếu đến file mscorlib.dll
trong file thực thi.
Nếu dùng Visual Studio để viết code, tính năng nhắc mã Intellisense sẽ liên tục hỗ trợ ta bằng cách gợi ý tên namespace, tên kiểu, tên method… mà nó tìm thấy trong các file dll.
File mscorlib.dll
là file mặc định mà trình biên dịch C# sẽ truy xuất. Đối với những file DLL khác, ta phải tạo tham chiếu đến chúng. Trong Visual Studio, ta click phải vào mục References trong Solution Explorer, sau đó chọn Add Reference… và chọn file DLL cần tham chiếu.
Việc gõ System.Console.WriteLine()
trở nên rườm rà không cần thiết. Do đó, ta viết lại đoạn code trên như sau:
1
2
3
4
5
6
7
8
9
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
}
}
Lệnh using
ở dòng 1 dùng để thông báo với trình biên dịch C# rằng nếu nó không tìm được Console.WriteLine()
thì nên tìm trong namespace System
. Ta cần lưu ý là lệnh using
trong C# không giống như #include
trong C++. using
không tham chiếu bất kì file nào trong hệ thống. Nó chỉ khai báo tên của namespace cần dùng để sau này ta không phải viết lại, giúp tiết kiệm thời gian đánh máy, đồng thời code cũng trở nên sáng sủa và gọn gàng.