Menu

Hello World trong C#: Main, Console.WriteLine và ReadLine

Chương trình C# đầu tiên của bạn, giải thích từng dòng: phương thức Main, Console.WriteLine và Write, đọc đầu vào bằng Console.ReadLine, chú thích, tạo và chạy project bằng dotnet CLI, và top-level statements.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Chương trình kinh điển đầu tiên in ra một dòng văn bản. Trong C#, nó trông như thế này:

Đầu ra:

Hello, World!

Giải thích từng dòng

  • using System; cho phép bạn viết Console thay vì tên đầy đủ System.Console. Console là một lớp trong namespace System (xem namespace và using).
  • class Program khai báo một lớp. Mọi code C# đều nằm trong một kiểu; tên Program là quy ước, không phải bắt buộc.
  • static void Main() là điểm bắt đầu (entry point). Khi chương trình khởi chạy, runtime tìm một phương thức static tên Main và gọi nó. static nghĩa là phương thức thuộc về chính lớp đó, nên không cần tạo đối tượng trước. void nghĩa là nó không trả về gì.
  • Console.WriteLine("Hello, World!"); gọi phương thức WriteLine với một đối số kiểu chuỗi. Mỗi câu lệnh kết thúc bằng dấu chấm phẩy.
  • Cặp ngoặc nhọn { } đánh dấu phần thân của lớp và của phương thức.

C# phân biệt chữ hoa chữ thường. console.writeline và main là những tên khác với Console.WriteLine và Main, và không tên nào trong số đó tồn tại.

Console.WriteLine và Console.Write

WriteLine xuống dòng sau văn bản. Write thì không, nên lần in tiếp theo tiếp tục trên cùng dòng. Cả hai nhận mọi kiểu, không chỉ chuỗi: số, boolean và đối tượng được chuyển đổi bằng phương thức ToString() của chúng.

Đầu ra:

Loading.. done
42
True

Item: coffee
coffee costs 3.20
coffee costs 3.20

Để ý rằng true được in ra thành True: đó là giá trị mà bool.ToString() trả về. Dạng $"...", gọi là nội suy chuỗi (string interpolation), là dạng bạn sẽ dùng nhiều nhất; xem nội suy chuỗi để biết các mã định dạng như :F2.

Đọc đầu vào bằng Console.ReadLine

Console.ReadLine() chờ người dùng gõ một dòng và nhấn Enter, rồi trả về dòng đó dưới dạng string không kèm ký tự xuống dòng. Khi hết đầu vào (ví dụ khi đầu vào được chuyển hướng từ một tệp đã đọc hết) nó trả về null.

Đầu ra:

What is your name? How old are you? 
Hi Maya, next year you will be 28.

Khi bạn chạy chương trình này trong terminal, văn bản bạn gõ sẽ hiện sau mỗi lời nhắc. Đầu ra ở trên không có văn bản được gõ vì đầu vào được chuyển hướng (pipe) chứ không phải gõ tay, nên chỉ những gì chương trình tự ghi mới hiện ra.

ReadLine luôn trả về văn bản. Để dùng giá trị như một số, bạn phải chuyển đổi nó. int.Parse(text) ném FormatException khi văn bản không phải là số; int.TryParse thì trả về false, vì vậy nó là lựa chọn đúng cho dữ liệu người dùng nhập. Chi tiết có trong chuyển đổi kiểu.

Hai phương thức liên quan: Console.Read() trả về ký tự tiếp theo dưới dạng mã int, và Console.ReadKey() đọc một lần nhấn phím mà không chờ Enter (chỉ hoạt động trong terminal tương tác).

Các dạng khác của phương thức Main

Main có thể nhận các đối số dòng lệnh và có thể trả về mã thoát. Tất cả đều là điểm bắt đầu hợp lệ:

static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)
static async Task Main()             // C# 7.1 and later
static async Task<int> Main(string[] args)  // C# 7.1 and later

Giá trị int được trả về trở thành mã thoát của tiến trình, thứ mà các script và hệ thống CI đọc để biết chương trình có chạy thành công không (theo quy ước, 0 nghĩa là thành công).

Đầu ra:

Got 0 argument(s)

Chạy bằng dotnet run -- apples pears thì args chứa "apples" và "pears". Dấu -- ngăn cách đối số dành cho chương trình của bạn với đối số dành cho công cụ dotnet.

Chú thích

C# có ba loại chú thích (comment). Trình biên dịch bỏ qua tất cả.

// A single-line comment runs to the end of the line.

/* A block comment
   can span several lines. */

/// <summary>
/// An XML documentation comment. Editors show it as the tooltip for the method.
/// </summary>
static decimal ApplyDiscount(decimal price) => price * 0.9m;

Dùng // cho ghi chú bên trong code. Chú thích /// đặt trên các kiểu và thành viên public; IDE hiển thị chúng khi bạn rê chuột lên một lời gọi, và trình biên dịch có thể xuất chúng ra tệp XML cho các công cụ tạo tài liệu.

Tạo và chạy project bằng dotnet

Trên máy của bạn, cài .NET SDK từ dotnet.microsoft.com, rồi:

dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!

dotnet new console tạo hai tệp: HelloApp.csproj (tệp project: target framework, cài đặt, tham chiếu package) và Program.cs. dotnet run biên dịch project rồi chạy. dotnet build biên dịch mà không chạy và ghi kết quả vào bin/Debug/net8.0/ (tên thư mục theo target framework của bạn).

Top-level statements (C# 9 trở lên)

Mở tệp Program.cs vừa được tạo, bạn sẽ thấy đúng thế này và không có gì khác:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

Đây là một chương trình dùng top-level statements, tính năng của C# 9. Trình biên dịch sinh lớp Program và phương thức Main bao quanh các câu lệnh của bạn. using System; cũng không có vì các project .NET 6 trở lên bật implicit usings: các namespace phổ biến như System, System.IO, System.Linq và System.Collections.Generic được import cho toàn bộ project.

Chương trình top-level vẫn đọc được args, dùng được await và return một mã thoát:

// C# 9 and later: the whole Program.cs
Console.Write("Name: ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! You passed {args.Length} arguments.");
return 0;

Mỗi project chỉ có một tệp được chứa top-level statements, và các kiểu (lớp, record) phải đặt sau chúng. Chú thích kiểu string? là nullable reference type (C# 8), và nó có mặt vì ReadLine có thể trả về null. Dạng class Program tường minh dùng trong các ví dụ trên trang này là tương đương, và là dạng bạn sẽ gặp trong code cũ và trong phần lớn script Unity, nên đáng để đọc được cả hai. Thêm --use-program-main vào dotnet new console nếu bạn thích dạng tường minh cho project mới.

Những lỗi bạn sẽ gặp đầu tiên

  • CS1002: ; expected. Một câu lệnh thiếu dấu chấm phẩy. Lỗi được báo ở cuối dòng bị thiếu.
  • CS0103: The name 'console' does not exist in the current context. Sai chữ hoa chữ thường, hoặc thiếu using System; trong project không bật implicit usings.
  • CS5001: Program does not contain a static 'Main' method suitable for an entry point. Main bị viết sai, không phải static, hoặc có chữ ký không được hỗ trợ.
  • CS0017: Program has more than one entry point defined. Hai lớp đều có Main. Giữ lại một, hoặc chọn một bằng thiết lập StartupObject trong .csproj.
  • Cửa sổ đóng ngay lập tức. Khi một ứng dụng console được mở bằng cách nhấp đúp, cửa sổ sẽ đóng khi Main trả về. Hãy chạy từ terminal, hoặc thêm Console.ReadKey(); ở cuối trong lúc thử nghiệm.

Câu hỏi thường gặp

Viết Hello World trong C# như thế nào?

Đặt Console.WriteLine("Hello, World!"); bên trong phương thức static void Main() của một lớp, với using System; ở đầu tệp. Trong project tạo bằng dotnet new console trên .NET 6 trở lên, cả tệp có thể chỉ gồm đúng một dòng đó, vì top-level statements tự sinh lớp và Main cho bạn.

Phương thức Main trong C# là gì?

Main là điểm bắt đầu (entry point): phương thức mà runtime gọi khi chương trình khởi chạy. Nó phải là static, có thể trả về void hoặc int (mã thoát), và có thể nhận tham số string[] args chứa các đối số dòng lệnh. Mỗi chương trình cần đúng một phương thức như vậy.

Console.Write và Console.WriteLine khác nhau thế nào?

Console.WriteLine ghi văn bản rồi xuống dòng, nên lần in tiếp theo bắt đầu ở dòng mới. Console.Write chỉ ghi văn bản, nên lần in tiếp theo tiếp tục trên cùng dòng. Console.WriteLine() không có đối số sẽ in ra một dòng trống.

Làm sao đọc dữ liệu người dùng nhập trong C#?

Console.ReadLine() đọc một dòng văn bản và trả về dưới dạng string (không kèm ký tự xuống dòng), hoặc null khi không còn đầu vào. Để lấy một số, hãy chuyển đổi chuỗi: int.TryParse(Console.ReadLine(), out int n) trả về false thay vì làm chương trình dừng lỗi khi văn bản không phải là số.

Làm sao chạy chương trình C# từ dòng lệnh?

Cài .NET SDK, rồi chạy dotnet new console -o HelloApp để tạo project, cd HelloApp, và dotnet run để build và chạy. dotnet build chỉ biên dịch, và đặt kết quả trong bin/Debug/net8.0/ (hoặc phiên bản bạn nhắm tới).

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu