C# là một ngôn ngữ lập trình đa năng, hiện đại và là loại ngôn ngữ lập trình hướng đối tượng được phát âm là “C Sharp”. Nó được phát triển bởi Microsoft do Anders Hejlsberg và nhóm của ông đứng đầu trong sáng kiến .NET và đã được Hiệp hội các nhà sản xuất máy tính Châu Âu (ECMA) và Tổ chức Tiêu chuẩn Quốc tế (ISO) phê duyệt. C# là một trong những ngôn ngữ dành cho cơ sở hạ tầng ngôn ngữ chung. C# rất giống với Java về mặt cú pháp và rất dễ dàng học và vận dụng đối với người dùng có kiến thức về C, C ++ hoặc Java.
Hiện nay, ngôn ngữ lập trình C# đã trở nên phổ cập và có thể sử dụng được cho nhiều ứng dụng khác nhau như: lập trình ứng dụng di động, phát triển trò chơi hay phát triển phần mềm doanh nghiệp. Trong công nghiệp, ngôn ngữ C# được sử dụng trong các ứng dụng lập trình nhúng, lập trình cho các bộ điều khiển (PLC, RTU, PAC,..) hay lập trình cho các phần mềm công nghiệp. Biết C# mở ra cho bạn rất nhiều cánh cửa lớn khi bạn xác định là một nhà phát triển, một lập trình viên trong tương lai.
Học phải đi đôi với hành, một mớ lý thuyết sẽ khiến bạn chán ngấy, khó hiểu, khó nhớ, khó đủ đường và sẽ làm bạn dễ dàng bỏ cuộc. Vậy chúng ta hãy bắt tay vào vừa học vừa thực hành ngay từ những thứ cơ bản (tạo chương trình Hello World đầu tiên) cho đến những kiến thức nâng cao nhé!
Hello World
Write Line
Console.WriteLine("Hello, world!"); // Prints: Hello, world!
Cú pháp Console.WriteLine()
được sử dụng để viết, in “text – văn bản” trong bảng điều khiển. Nó cũng có thể được sử dụng để in các kiểu dữ liệu và giá trị khác được lưu trữ trong các biến.
Read Line
Console.WriteLine("Enter your name: "); name = Console.ReadLine();
Cú pháp Console.ReadLine()
được sử dụng để lấy thông tin đầu vào của người dùng. Đầu vào của người dùng có thể được lưu trữ trong một biến. Cú pháp này cũng có thể được sử dụng để nhắc người dùng nhấn ENTER trên bàn phím.
Comments
// This is a single line comment /* This is a multi-line comment and continues until the end of comment symbol is reached */
Chú thích (“nhận xét”, “bình luận”) là các đoạn văn bản không được thực thi. Những dòng này có thể được sử dụng nhằm để lại ghi chú với mục đích tăng tính dễ đọc cho chương trình.
- Ghi chú dòng đơn được tạo với hai dấu gạch chéo về phía trước
//
. - Ghi chú nhiều dòng được tạo bắt đầu với
/*
và kết thúc với*/
. Nó rất hữu ích cho việc ghi chú các khối mã lớn.
.NET Platform
.NET là một mã nguồn mở, miễn phí, đa nền tảng, được các nhà phát triển sử dụng để xây dựng nhiều ứng dụng khác nhau.
Với .NET, bạn có thể sử dụng đa ngôn ngữ, trình chỉnh sửa và các thư viện có sẵn để xây dựng ứng dụng cho web, thiết bị di động, máy tính PC, trò chơi hay IoT. Cho dù bạn đang sử dụng ngôn ngữ C#, F# hay Visual Basic để làm việc thì code của bạn sẽ chạy nguyên bản trên bất kỳ hệ điều hành nào tương thích với nền tảng .NET và sẽ giúp bạn xử lý các công việc nặng nhọc một cách dễ dàng hơn.
Biến và kiểu dữ liệu trong C#
Write Line
Console.WriteLine("Hello, world!"); // Prints: Hello, world!
Cú pháp Console.WriteLine()
được sử dụng để viết, in “text – văn bản” trong bảng điều khiển. Nó cũng có thể được sử dụng để in các kiểu dữ liệu và giá trị khác được lưu trữ trong các biến.
Biến và loại biến trong C#
string foo = "Hello"; string bar = "How are you?"; int x = 5; Console.WriteLine(foo); // Prints: Hello
Trong ngôn ngữ lập trình C# (C Sharp), một biến là một cách để lưu trữ dữ liệu trong bộ nhớ của máy tính để được sử dụng sau này (tái sử dụng) trong chương trình. C# là một ngôn ngữ tường minh, nghĩa là khi các biến được khai báo thì cần phải xác định kiểu dữ liệu của chúng..
Việc khai báo các loại biến cho phép trình biên dịch dừng chương trình đang chạy khi các biến được sử dụng sai, tức là một lệnh int
được sử dụng thì cần sử dụng một string
hoặc ngược lại..
Toán tử số học
int result; result = 10 + 5; // 15 result = 10 - 5; // 5 result = 10 * 5; // 50 result = 10 / 5; // 2 result = 10 % 5; // 0
Toán tử số học được sử dụng để sửa đổi các giá trị số:
+
cộng toán tử-
trừ toán tử*
nhân toán tử/
chia toán tử%
toán tử modulo (trả lại phần còn lại)
Kết hợp toán tử (Unary Operator)
int a = 10; a++; Console.WriteLine(a); // Prints: 11
Các toán tử có thể được kết hợp để tạo ra các câu lệnh ngắn hơn nhằm sửa đổi các biến hiện có nhanh chóng hơn. Hai ví dụ phổ biến:
++
tăng một giá trị toán tử.--
giảm một giá trị toán tử.
Tìm căn bậc 2 trong C#
// Input positive value, Output square root of x Console.Write(Math.Sqrt(x)); //OUTPUT: 9
Trong ngôn ngữ lập trình C#, Math.Sqrt()
là hàm được sử dụng để tính căn bậc 2 của giá trị được chỉ định.
Math.Pow() trong C#
// Find power using Math.Pow // 6 is base and 2 is power or // index or exponent of a number double pow_ab = Math.Pow(6, 2); // Print the result Console.WriteLine(pow_ab); //OUTPUT: 36
Trong C#, Math.Pow()
là hàm được sử dụng để nâng một số lên lũy thừa xác định. Nó sẽ trả về một số loại kép.
Nối chuỗi ký tự trong C#
// Declare strings string firstName = "Divyesh"; string lastName = "Goardnan"; // Concatenate two string variables string name = firstName + " " + lastName; Console.WriteLine(name); //Ths code will output Divyesh Goardnan
Nối chuỗi là quá trình nối một chuỗi vào một chuỗi khác. Phương pháp đơn giản nhất để nối hai chuỗi trong C # là sử dụng toán tử +.
Ký tự tự thoát trong C#
Trong ngôn ngữ lập trình C # (C Sharp), một chuỗi thoát đề cập đến một tổ hợp các ký tự bắt đầu bằng dấu gạch chéo ngược “\” và theo sau là các chữ cái hoặc chữ số. Nó được sử dụng để đảm bảo rằng chương trình đọc các ký tự nhất định như một phần của chuỗi. Ví dụ, nó có thể được sử dụng để lấy các ký tự trong dấu ngoặc kép trong một chuỗi mà bạn muốn in ra bảng điều khiển. Chuỗi tự thoát cũng có thể làm những việc khác bằng cách sử dụng các ký tự cụ thể. Ví dụ: \ n được sử dụng để tạo ra một dòng mới.
Nội suy chuỗi trong C#
int id = 100 // We can use an expression with a string interpolation. string multipliedNumber = $"The multiplied ID is {id * 10}."; Console.WriteLine(multipliedNumber); // This code would output "The multiplied ID is 1000."
Nội suy chuỗi là sử dụng các cú pháp dễ đọc và thuận tiện hơn để tạo ra chuỗi được định dạng. Nó cho phép chèn các giá trị và biểu thức biến vào giữa một chuỗi và không phải lo lắng về dấu chấm câu hoặc dấu cách.
String New-Line
Console.WriteLine("Hello\nWorld"); // The console output will look like: // Hello // World
Sự kết hợp ký tự \n
đại diện cho một phương thức tạo một dòng ký tự mới bên trong string
của ngôn ngữ C#.
Ví dụ như: "Hello\nWorld"
trong Console.WriteLine()
sẽ in ra dòng Hello
và World
trên các dòng riêng biệt trong bảng điều khiển.
.toUpper() trong C#
string str2 = "This is C# Program xsdd_$#%"; // string converted to Upper case string upperstr2 = str2.ToUpper(); //upperstr2 contains "THIS IS C# PROGRAM XSDD_$#%"
Trong C#, .ToUpper()
được sử dụng để chuyển đổi mọi ký tự trong chuỗi thành chữ hoa. Nếu một ký tự không có chữ hoa tương đương thì nó sẽ không thay đổi. Ví dụ, các ký hiệu đặc biệt không thay đổi.
.ToLower() trong C#
string mixedCase = "This is a MIXED case string."; // Call ToLower instance method, which returns a new copy. string lower = mixedCase.ToLower(); //variable lower contains "this is a mixed case string."
Trong C#, .ToLower()
được sử dụng để chuyển đổi mọi ký tự trong chuỗi thành chữ thường. Nếu một ký tự không có chữ thường tương đương thì nó sẽ không thay đổi. Ví dụ, các ký hiệu đặc biệt không thay đổi.
Độ dài chuỗi (String Length) trong C#
string a = "One example"; Console.WriteLine("LENGTH: " + a.Length); // This code outputs 11
Trong hàm string
có lớp thuộc tính Length, thuộc tính này trả về số ký tự trong chuỗi.
IndexOf() trong C#
string str = "Divyesh"; // Finding the index of character // which is present in string and // this will show the value 5 int index1 = str.IndexOf('s'); Console.WriteLine("The Index Value of character 's' is " + index1); //The Index Value of character 's' is 5
Trrong C#, IndexOf()
được sử dụng để tìm vị trí chỉ mục của một ký tự được chỉ định trong một chuỗi. Kết quả trả về -1 nếu không tìm thấy ký tự.
Substring() trong C#
string myString = "Divyesh"; string test1 = myString.Substring(2);
Trong ngôn ngữ lập trình C# (C Sharp), Substring()
được sử dụng để truy xuất một phần của chuỗi trong khi vẫn giữ nguyên dữ liệu gốc. Chuỗi con mà bạn truy xuất có thể được lưu trữ trong một biến để sử dụng ở những nơi khác trong chương trình của bạn.
Ký hiệu dấu ngoặc []
// Get values from this string. string value = "Dot Net Perls"; //variable first contains letter D char first = value[0]; //Second contains letter o char second = value[1]; //last contains letter s char last = value[value.Length - 1];
Chuỗi chứa các ký tự. Một cách có thể truy vấn được các giá trị char
này là bằng ký hiệu dấu ngoặc […]. Thậm chí có thể lưu trữ các ký tự này trong các biến riêng biệt.
Truy cập một ký tự cụ thể bằng cách sử dụng dấu ngoặc vuông […] trên chuỗi, đặt vị trí chỉ mục của ký tự mong muốn giữa các dấu ngoặc. Ví dụ, để lấy ký tự đầu tiên, bạn có thể chỉ định là variable[0]
. Để lấy ký tự cuối cùng, bạn lấy độ dài của chuỗi trừ đi một ký tự .
Read Line
Console.WriteLine("Enter your name: "); name = Console.ReadLine();
Lệnh Console.ReadLine()
được sử dụng để lấy thông tin đầu vào của người dùng. Đầu vào của người dùng có thể được lưu trữ trong một biến. Cú pháp này cũng có thể được sử dụng để nhắc người dùng nhấn ENTER trên bàn phím.
Bình luận trong C#
// This is a single line comment /* This is a multi-line comment and continues until the end of comment symbol is reached */
Chú thích (“nhận xét”, “bình luận”) là các đoạn văn bản không được thực thi. Những dòng này có thể được sử dụng nhằm để lại ghi chú với mục đích tăng tính dễ đọc cho chương trình.
- Ghi chú dòng đơn được tạo với hai dấu gạch chéo về phía trước
//
. - Ghi chú nhiều dòng được tạo bắt đầu với
/*
và kết thúc với*/
. Nó rất hữu ích cho việc ghi chú các khối mã lớn.
Logic và Điều kiện
Bảng Logic (Truth Table)
Bảng Logic là một cách để dễ dàng hình dung logic boolean. Vì boolean chỉ có hai giá trị khả dụng, điều đó có nghĩa là chúng ta có thể liệt kê một cách gọn gàng trong bảng tất cả các cặp đầu vào và đầu ra có thể xảy ra cho toán tử boolean đơn phân và nhị phân.
Hình ảnh dưới đây thể hiện Bảng Logic cho các toán tử NOT, AND, NAND, OR, NOR, XOR và XNOR. Đối với mỗi hàng, cột cuối cùng đại diện cho đầu ra và các cột khác là đầu vào cho toán tử tương ứng.
Kiểu Boolean
bool skyIsBlue = true; bool penguinsCanFly = false; Console.WriteLine($"True or false, is the sky blue? {skyIsBlue}."); /* This simple program illustrates how booleans are declared. However, the real power of booleans requires additional programming constructs such as conditionals.*/
Cú pháp bool
trả về kiểu dữ liệu true
hoặc false
và sẽ dựa trên tính hợp lệ của tất cả các câu lệnh logic phải là đúng hoặc sai.
Mã hóa Boolean vào máy tính, cho phép tự suy luận logic trong các chương trình. Hiểu theo nghĩa rộng, máy tính có thể mã hóa tính trung thực hay sai lệch của một dữ liệu được chỉ định và dựa trên thông tin đó, hoàn toàn thay đổi hoạt động của chương trình.
Biểu thức Boolean
// These expressions all evaluate to a boolean value. // Therefore their values can be stored in boolean variables. bool a = (2 > 1); bool b = a && true; bool c = !false || (7 < 8);
Biểu thức boolean là những biểu thức bất kỳ nào được đánh giá hoặc trả về giá trị boolean.
Toán tử so sánh trong C#
int x = 5; Console.WriteLine(x < 6); // Prints "True" because 5 is less than 6. Console.WriteLine(x > 8); // Prints "False" because 5 is not greater than 8. string foo = "foo"; Console.WriteLine(foo == "bar"); // Prints "False" because "foo" does not equal "bar".
Một toán tử so sánh, như tên của nó, so sánh hai biểu thức và trả về true
hoặc false
tùy thuộc vào kết quả của phép so sánh. Ví dụ: nếu chúng ta so sánh hai giá trị int
, chúng ta có thể kiểm tra xem một số có lớn hơn số kia hay không hoặc cả hai số đều bằng nhau. Tương tự, chúng ta có thể kiểm tra một string
có bằng nhau với một string
khác không.
Toán tử Logic trong C#
// These variables equal true. bool a = true && true; bool b = false || true; bool c = !false; // These variables equal false. bool d = true && false; bool e = false || false; bool f = !true;
Toán tử logic nhận biểu thức boolean làm đầu vào và trả về giá trị boolean.
Toán tử &&
nhận 2 biểu thức boolean và chỉ trả về giá trị true
nếu cả 2 đều được đánh giá là true
.
Toán tử ||
nhận 2 biểu thức boolean và trả về giá trị là true
nếu 1 trong 2 biểu thức được đánh giá là true
.
Toán tử !
nhận 1 biểu thức boolean và trả về giá trị ngược lại.
Luồng điều khiển (Control Flow)
Trong lập trình, luồng điều khiển là thứ tự thực hiện các câu lệnh và lệnh. Người lập trình có thể thay đổi luồng điều khiển của chương trình bằng cách sử dụng các cấu trúc điều khiển có điều kiện.
Khả năng thay đổi quy trình và kiểm soát của chương trình rất mạnh mẽ vì nó cho phép chúng ta điều chỉnh hoạt động của chương trình đang chạy tùy thuộc vào trạng thái của chương trình. Ví dụ: giả sử một người dùng đang sử dụng ứng dụng ngân hàng và muốn rút 1.000.000 VND. Chúng ta chắc chắn muốn ứng dụng hoạt động với các cơ chế khác nhau tùy thuộc vào việc người dùng có 20.000 VND hay 50.000.000 VND trong tài khoản ngân hàng của họ!
Điều khiển có điều kiện (Conditional Control)
Câu lệnh điều kiện hoặc cấu trúc điều khiển có điều kiện cho phép một chương trình có các hành động khác nhau tùy thuộc vào các điều kiện nhất định được đáp ứng.
Về mặt trực quan, điều này bắt chước cách con người đưa ra các quyết định và hành động theo chúng. Ví dụ, lý luận về việc đi ra ngoài có thể như sau:
- Điều kiện: bên ngoài trời có mưa không?
- Nếu trời đang mưa, hãy mang theo ô.
- Nếu trời không mưa, thì không mang theo ô.
Chúng ta có thể tiếp tục thêm các mệnh đề để làm cho lập luận trở nên phức tạp hơn, chẳng hạn như “Nếu trời nắng thì hãy bôi kem chống nắng”.
Câu lệnh If (nếu-thì) trong C#
if (true) { // This code is executed. Console.WriteLine("Hello User!"); } if (false) { // This code is skipped. Console.WriteLine("This won't be seen :("); }
Trong ngôn ngữ lập trình C # (C Sharp), câu lệnh if thực thi một chức năng dựa trên việc biểu thức boolean được cung cấp trong dấu ngoặc đơn có “phải” hay “không” <=> true
hay false
.
Nếu là “phải” tức là true
thì sẽ thực hiện tiếp các mã, khối lệnh trong dấu ngoặc {}
, nếu “không” thì sẽ bỏ qua.
Câu lệnh Else (không thì) trong C#
if (true) { // This block will run. Console.WriteLine("Seen!"); } else { // This will not run. Console.WriteLine("Not seen!"); } if (false) { // Conversely, this will not run. Console.WriteLine("Not seen!"); } else { // Instead, this will run. Console.WriteLine("Seen!"); }
Một lệnh else
theo sau sẽ là dấu ngoặc {}
chứa một khối mã lệnh. Trước lệnh else
thì phải có mệnh đề khác đặt trước câu lệnh if
.
Khối bên trong dấu ngoặc của lệnh else
chỉ được thực hiện khi điều kiện của câu lệnh if
là false
. Tức là khối mã lệnh trong câu lệnh if
không được thực thi thì khi đó mới đến khối mã lệnh trong câu lệnh else
.
If và Else If (nếu-nếu không thì) trong C#
int x = 100, y = 80; if (x &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; y) { Console.WriteLine("x is greater than y"); } else if (x &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; y) { Console.WriteLine("x is less than y"); } else { Console.WriteLine("x is equal to y"); }
Một mã câu lệnh phổ biến khi viết nhiều câu lệnh if
và else
là có một khối lệnh else
được lồng câu lệnh if
, và có thể chứa thêm lệnh else
khác, etc. Một cách tốt hơn để thể hiện những chức năng này trong C# là sử dụng lệnh else if
. Điều kiện đầu tiên được đánh giá là true
thì sẽ chạy khối mã được liên kết của nó. Nếu được đánh giá là false
, thì các khối mã lệnh else
sẽ được chạy (nếu tồn tại).
Lệnh Switch trong C#
// The expression to match goes in parentheses. switch (fruit) { case "Banana": // If fruit == "Banana", this block will run. Console.WriteLine("Peel first."); break; case "Durian": Console.WriteLine("Strong smell."); break; default: // The default block will catch expressions that did not match any above. Console.WriteLine("Nothing to say."); break; } // The switch statement above is equivalent to this: if (fruit == "Banana") { Console.WriteLine("Peel first."); } else if (fruit == "Durian") { Console.WriteLine("Strong smell."); } else { Console.WriteLine("Nothing to say."); }
Lệnh switch
là một cấu trúc luồng điều khiển đánh giá một biểu thức và quyết định khối mã nào sẽ chạy bằng cách xét độ khớp kết quả của biểu thức với từng trường hợp case
. Nói chung, một khối mã được thực thi khi giá trị cho case
bằng với biểu thức được đánh giá, tức là khi sử dụng toán tử so sánh ==
giữa hai giá trị trả về true
. Lệnh switch
thường được dùng để thay thế cho cấu trúc lệnh if else
khi điều kiện kiểm tra đều là sự so sánh bằng hay không bằng một giá trị.
Lệnh ngắt (Break) trong C#
string color = "blue"; switch (color) { case "red": Console.WriteLine("I don't like that color."); break; case "blue": Console.WriteLine("I like that color."); break; default: Console.WriteLine("I feel ambivalent about that color."); break; } // Regardless of where the break statement is in the above switch statement, // breaking will resume the program execution here. Console.WriteLine("- Steve");
Một trong những công dụng của lệnh break
trong C# là để thoát ra khỏi khối lệnh switch
/case
và sau đó tiếp tục thực thi các chương trình sau khối mã lệnh switch
. Trong C#, mỗi khối mã case
trong một câu lệnh switch
cần được thoát ra bằng lệnh break
(hoặc bằng một số câu lệnh jump khác), nếu không thì chương trình sẽ không thể biên dịch. Nó sẽ được gọi ra sau khi tất cả các chương trình cụ thể trong case
đã được thực thi.
Toán tử bậc 3 (Ternary Operator)
bool isRaining = true; // This sets umbrellaOrNot to "Umbrella" if isRaining is true, // and "No Umbrella" if isRaining is false. string umbrellaOrNot = isRaining ? "Umbrella" : "No Umbrella"; // "Umbrella" Console.WriteLine(umbrellaOrNot);
Trong C #, toán tử bậc ba là một cú pháp đặc biệt có dạng: condition ? expression1 : expression2
.
Nó nhận một điều kiện boolean và hai biểu thức làm đầu vào. Không giống như câu lệnh if
statement, toán tử bậc ba tự nó là một biểu thức. Nó đánh giá biểu thức đầu vào đầu tiên hoặc biểu thức đầu vào thứ hai tùy thuộc vào điều kiện tương ứng là đúng hay sai tức là true
hay false
.
Phương thức (Methods)
Phương thức bên trong các biến
static void DeclareAndPrintVars(int x) { int y = 3; // Using x and y inside the method is fine. Console.WriteLine(x + y); } static void Main() { DeclareAndPrintVars(5); // x and y only exist inside the body of DeclareAndPrintVars, so we cannot use them here. Console.WriteLine(x * y); }
Không thể sử dụng các tham số và biến được khai báo bên trong một phương thức bên ngoài phần thân của phương thức. Cố gắng làm như vậy sẽ gây ra lỗi khi biên dịch chương trình!
Các tham số tùy chọn trong C#
// y and z are optional parameters. static int AddSomeNumbers(int x, int y = 3, int z = 2) { return x + y + z; } // Any of the following are valid method calls. AddSomeNumbers(1); // Returns 6. AddSomeNumbers(1, 1); // Returns 4. AddSomeNumbers(3, 3, 3); // Returns 9.
Trong C #, các phương thức có thể được cung cấp các tham số tùy chọn. Một tham số là tùy chọn nếu khai báo của nó chỉ định một đối số mặc định. Các phương thức với một tham số tùy chọn có thể được gọi có hoặc không có truyền vào một đối số cho tham số đó. Nếu một phương thức được gọi mà không truyền đối số cho tham số tùy chọn, thì tham số được khởi tạo với giá trị mặc định của nó.
Để xác định một tham số tùy chọn, hãy sử dụng dấu bằng sau phần khai báo tham số, theo sau là giá trị mặc định của nó.
Lệnh trả về (Return) trong C#
static int ReturnAValue(int x) { // We return the result of computing x * 10 back to the caller. // Notice how we are returning an int, which matches the method's return type. return x * 10; } static void Main() { // We can use the returned value any way we want, such as storing it in a variable. int num = ReturnAValue(5); // Prints 50 to the console. Console.WriteLine(num); }
Trong C #, câu lệnh return
có thể được sử dụng để trả về một giá trị từ một phương thức và trở lại trình gọi của phương thức đó.
Khi lệnh return
được gọi, phương thức hiện tại kết thúc và sẽ điều khiển được trả về nơi phương thức ban đầu được gọi. Giá trị được phương thức trả về phải khớp với kiểu trả về của phương thức, được chỉ định trong khai báo phương thức.
Kiểu trả về Void (Void Return Type)
// This method has no return value static void DoesNotReturn() { Console.WriteLine("Hi, I don't return like a bad library borrower."); } // This method returns an int static int ReturnsAnInt() { return 2 + 3; }
Trong C #, các phương thức không return
một giá trị có một kiểu trả về void
.
void
không phải là một kiểu dữ liệu thực tế như int
hay string
, vì nó đại diện cho việc thiếu đầu ra hoặc giá trị.
Tham số Out
// f1, f2, and f3 are out parameters, so they must be prefixed with `out`. static void GetFavoriteFoods(out string f1, out string f2, out string f3) { // Notice how we are assigning values to the parameters instead of using `return`. f1 = "Sushi"; f2 = "Pizza"; f3 = "Hamburgers"; } static void Main() { string food1; string food2; string food3; // Variables passed to out parameters must also be prefixed with `out`. GetFavoriteFoods(out food1, out food2, out food3); // After the method call, food1 = "Sushi", food2 = "Pizza", and food3 = "Hamburgers". Console.WriteLine($"My top 3 favorite foods are {food1}, {food2}, and {food3}"); }
return
chỉ có thể trả về một giá trị. Khi cần nhiều giá trị thì có thể sử dụng tham số out
.
Tham số
out
được bắt đầu bằng out
trong tiêu đề phương thức. Khi được gọi, đối số cho mỗi tham số out
phải là một biến có tiền tố out
.
Tham số out
số trở thành bí danh (tên thứ 2) cho các biến được chuyển vào. Vì vậy, chúng ta có thể gán giá trị cho các tham số và chúng sẽ tồn tại trên các biến mà chúng ta đã truyền vào sau khi phương thức kết thúc.
Khai báo phương thức
// This is an example of a method header. static int MyMethodName(int parameter1, string parameter2) { // Method body goes here... }
Trong C #, một khai báo phương thức, còn được gọi là tiêu đề phương thức, bao gồm mọi thứ về phương thức ngoài phần thân của phương thức. Khai báo phương thức bao gồm:
- tên phương thức
- kiểu tham số
- thứ tự tham số
- tên tham số
- kiểu trả về
- bổ ngữ tùy chọn
Khai báo phương thức thường thấy là khai báo cho phương thức Main
(có thể khai báo nhiều Main
): static void Main(string[] args)
Phần thân của phương thức
static int Add(int x, int y) { return x + y; } static void PrintUpper(string str) { Console.WriteLine(str.ToUpper()); } // The same methods written in expression-body form. static int Add(int x, int y) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; x + y; static void PrintUpper(string str) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; Console.WriteLine(str.ToUpper());
Trong C #, thân phương thức là các biểu thức ngắn được viết bằng một cú pháp ngắn gọn đặc biệt. Một phương thức chỉ có thể được viết ở dạng thân biểu thức khi thân phương thức bao gồm một câu lệnh hoặc biểu thức duy nhất. Nếu phần thân là một biểu thức đơn lẻ, thì biểu thức đó được sử dụng làm giá trị trả về của phương thức.
Cú pháp chung là returnType funcName(args...) => expression;
. Lưu ý cách ký hiệu =>
, được sử dụng thay cho dấu ngoặc nhọn. Cũng lưu ý rằng lệnh return
là không cần thiết, vì biểu thức được trả về ngầm định.
Biểu thức Lambda
int[] numbers = { 3, 10, 4, 6, 8 }; static bool isTen(int n) { return n == 10; } // `Array.Exists` calls the method passed in for every value in `numbers` and returns true if any call returns true. Array.Exists(numbers, isTen); Array.Exists(numbers, (int n) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { return n == 10; }); // Typical syntax // (input-parameters) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;statements&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; }
Biểu thức lambda là một khối mã được xử lý giống như bất kỳ giá trị hoặc biểu thức nào khác. Nó có thể được truyền vào các phương thức, được lưu trữ trong các biến và được tạo ra bên trong các phương thức.
Đặc biệt, các biểu thức lambda rất hữu ích để tạo các phương thức ẩn danh, các phương thức không có tên, để được truyền vào các phương thức yêu cầu đối số phương thức. Cú pháp ngắn gọn của chúng thanh lịch hơn so với khai báo một phương thức thông thường khi chúng được sử dụng như một đối số phương thức riêng lẻ.
Biểu thức Lambda ngắn gọn (Shorter Lambda)
int[] numbers = { 7, 7, 7, 4, 7 }; Array.Find(numbers, (int n) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { return n != 7; }); // The type specifier on `n` can be inferred based on the array being passed in and the method body. Array.Find(numbers, (n) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { return n != 7; }); // The parentheses can be removed since there is only one parameter. Array.Find(numbers, n =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { return n != 7; }); // Finally, we can apply the rules for expression-bodied methods. Array.Find(numbers, n =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; n != 7);
Có nhiều cách để rút ngắn cú pháp biểu thức lambda cho ngắn gọn.
- Kiểu tham số có thể được loại bỏ nếu nó có thể được suy ra.
- Dấu ngoặc đơn có thể được loại bỏ nếu chỉ có một tham số.
Lưu ý thêm, các quy tắc thông thường cho các phương thức thể hiện biểu thức cũng áp dụng cho biểu thức lambda.
Mảng và vòng lặp (Arrays & Loops)
Mảng (Arrays) trong C#
// `numbers` array that stores integers int[] numbers = { 3, 14, 59 }; // 'characters' array that stores strings string[] characters = new string[] { "Huey", "Dewey", "Louie" };
Trong C #, một mảng là một cấu trúc đại diện cho một tập hợp các giá trị hoặc đối tượng có cùng kiểu theo thứ tự có độ dài cố định.
Mảng giúp dễ dàng tổ chức và vận hành trên một lượng lớn dữ liệu. Ví dụ: thay vì tạo 100 biến số nguyên, bạn chỉ cần tạo một mảng lưu trữ tất cả các số nguyên đó!
Khai báo mảng trong C#
// Declare an array of length 8 without setting the values. string[] stringArray = new string[8]; // Declare array and set its values to 3, 4, 5. int[] intArray = new int[] { 3, 4, 5 };
Biến mảng trong C # được khai báo tương tự như một biến không phải là mảng, với việc bổ sung dấu ngoặc vuông ([]
) sau mã lệnh định dạng kiểu để biểu thị nó là một mảng.
Lệnh new
được sử dụng khi khởi tạo một mảng mới để gán cho biến, cũng như độ dài mảng trong dấu ngoặc vuông. Mảng cũng có thể được khởi tạo bằng các giá trị bằng dấu ngoặc nhọn ({}
). Trong trường hợp này, độ dài mảng là không cần thiết.
Khai báo và khởi tạo mảng cùng một lúc
// `numbers` and `animals` are both declared and initialized with values. int[] numbers = { 1, 3, -10, 5, 8 }; string[] animals = { "shark", "bear", "dog", "raccoon" };
Trong C #, một cách được sử dụng để một mảng có thể được khai báo và khởi tạo cùng một lúc là gán mảng mới khai báo vào danh sách các giá trị được phân tách bằng dấu phẩy bao quanh bởi dấu ngoặc nhọn ({}
). Lưu ý cách chúng ta có thể bỏ qua kiểu định dạng và từ new
ở phía bên phải của bài tập khi sử dụng cú pháp này. Điều này chỉ có thể thực hiện được trong khi khai báo mảng.
Truy cập phần tử mảng
// Initialize an array with 6 values. int[] numbers = { 3, 14, 59, 26, 53, 0 }; // Assign the last element, the 6th number in the array (currently 0), to 58. numbers[5] = 58; // Store the first element, 3, in the variable `first`. int first = numbers[0];
Trong ngôn ngữ lập trình C# (C Sharp), các phần tử của một mảng được gắn nhãn tăng dần, bắt đầu từ 0 cho phần tử đầu tiên. Ví dụ: phần tử thứ 3 của một mảng sẽ được lập chỉ mục ở số 2 và phần tử thứ 6 của mảng sẽ được lập chỉ mục ở số 5 của mảng.
Một phần tử cụ thể có thể được truy cập bằng cách sử dụng toán tử dấu ngoặc vuông, bao quanh chỉ mục bằng dấu ngoặc vuông. Sau khi được truy cập, phần tử có thể được sử dụng trong một biểu thức hoặc được sửa đổi như một biến thông thường.
Độ dài mảng (Array Length) trong C#
int[] someArray = { 3, 4, 1, 6 }; Console.WriteLine(someArray.Length); // Prints 4 string[] otherArray = { "foo", "bar", "baz" }; Console.WriteLine(otherArray.Length); // Prints 3
Thuộc tính Length của một mảng C # có thể được sử dụng để lấy số phần tử trong một mảng cụ thể.
Vòng lặp For trong C#
// This loop initializes i to 1, stops looping once i is greater than 10, and increases i by 1 after each loop. for (int i = 1; i &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;= 10; i++) { Console.WriteLine(i); } Console.WriteLine("Ready or not, here I come!");
Vòng lặp for trong C# dùng thực hiện một tập hợp các lệnh cho một số lần xác định, dựa trên ba biểu thức được cung cấp. Ba biểu thức được phân tách bằng dấu chấm phẩy và theo thứ tự là:
- Khởi tạo: Điều này được chạy chính xác một lần khi bắt đầu vòng lặp, thường được sử dụng để khởi tạo biến cho biến lặp của vòng lặp.
- Điều kiện dừng: Biểu thức boolean này được kiểm tra trước mỗi lần lặp để xem nó có chạy tiếp hay không.
- Câu lệnh lặp: Được thực hiện sau mỗi lần lặp của vòng lặp, thường được sử dụng để cập nhật biến trình lặp.
Vòng lặp For Each trong C#
string[] states = { "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado" }; foreach (string state in states) { // The `state` variable takes on the value of an element in `states` and updates every iteration. Console.WriteLine(state); } // Will print each element of `states` in the order they appear in the array.
Một vòng lặp foreach
trong C # dùng để chạy một tập hợp các lệnh một lần cho mỗi phần tử trong một tập hợp nhất định. Ví dụ: nếu một mảng có 200 phần tử, thì phần thân của vòng lặp foreach
sẽ thực thi 200 lần. Khi bắt đầu mỗi lần lặp, một biến được khởi tạo cho phần tử hiện tại đang được xử lý.
Nó được khai báo bằng lệnh foreach
. Tiếp theo, trong dấu ngoặc đơn, một loại biến và tên biến theo sau là từ in
và tập hợp để lặp lại.
Vòng lặp While trong C#
string guess = ""; Console.WriteLine("What animal am I thinking of?"); // This loop will keep prompting the user, until they type in "dog". while (guess != "dog") { Console.WriteLine("Make a guess:"); guess = Console.ReadLine(); } Console.WriteLine("That's right!");
Trong C #, vòng lặp while thực thi một tập hợp các lệnh liên tục trong khi biểu thức boolean đã cho đánh giá là true
hoặc một trong các lệnh bên trong thân vòng lặp, chẳng hạn như lệnh break
kết thúc vòng lặp.
Lưu ý rằng phần thân của vòng lặp có thể hoàn toàn không chạy, vì điều kiện boolean được đánh giá trước lần lặp đầu tiên của vòng lặp while.
Cú pháp khai báo vòng lặp while đơn giản là từ while
theo sau là điều kiện boolean trong ngoặc đơn.
Vòng lặp Do While trong C#
do { DoStuff(); } while(boolCondition); // This do-while is equivalent to the following while loop. DoStuff(); while (boolCondition) { DoStuff(); }
Trong C #, vòng lặp do while chạy một tập các lệnh một lần và sau đó tiếp tục chạy miễn là điều kiện boolean đã cho là true
. Lưu ý rằng quá trình này gần giống với vòng lặp while, với điểm khác biệt là do while chạy một hoặc nhiều lần và vòng lặp while không chạy hoặc chạy nhiều lần.
Cú pháp khai báo do while là từ do
tiếp theo là khối mã, sau đó là từ while
với điều kiện boolean trong ngoặc đơn. Lưu ý rằng dấu chấm phẩy là cần thiết để kết thúc vòng lặp do while.
Vòng lặp vô hạn trong C#
while (true) { // This will loop forever unless it contains some terminating statement such as `break`. }
Vòng lặp vô hạn là vòng lặp không bao giờ kết thúc vì điều kiện dừng của nó luôn false
. Một vòng lặp vô hạn có thể hữu ích nếu một chương trình bao gồm liên tục thực thi một đoạn mã. Tuy nhiên, một vòng lặp vô hạn không chủ ý có thể khiến một chương trình bị treo và không phản hồi do bị mắc kẹt trong vòng lặp.
Một chương trình đang chạy trong một trình bao hoặc thiết bị đầu cuối bị mắc kẹt trong một vòng lặp vô hạn có thể được kết thúc bằng cách chấm dứt quá trình.
Lệnh Jump trong C#
while (true) { Console.WriteLine("This prints once."); // A `break` statement immediately terminates the loop that contains it. break; } for (int i = 1; i &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;= 10; i++) { // This prints every number from 1 to 10 except for 7. if (i == 7) { // A `continue` statement skips the rest of the loop and starts another iteration from the start. continue; } Console.WriteLine(i); } static int WeirdReturnOne() { while (true) { // Since `return` exits the method, the loop is also terminated. Control returns to the method's caller. return 1; } }
Câu lệnh nhảy được sử dụng để cung cấp cho lập trình viên quyền kiểm soát bổ sung đối với luồng điều khiển của chương trình. Chúng rất thường được sử dụng trong ngữ cảnh của các vòng lặp để thoát khỏi vòng lặp hoặc để bỏ qua các phần của vòng lặp.
Các lệnh kiểm soát luồng bao gồm break
, continue
, và return
.
Lớp và đối tường (Class & Object)
Class trong C#
using System; namespace BasicClasses { class Forest { public string name; public int trees; } } // Here we have the Forest class which has two pieces of data, called fields. They are the "name" and "trees" fields.
Trong C #, các lớp được sử dụng để tạo các kiểu tùy chỉnh. Lớp định nghĩa các loại thông tin và phương thức có trong một loại tùy chỉnh.
Thành viên (Member) trong C#
class Forest { public string name; public string Name { get { return name; } set { name = value; } } } // A member of a class can be a field (like name), a property (like Name) or a method (like get()/set()). It can also be any of the following: // Constants // Constructors // Events // Finalizers // Indexers // Operators // Nested Types
Trong ngôn ngữ lập trình C# (C Sharp), một lớp (class) chứa các thành viên (member), xác định loại dữ liệu được lưu trữ trong một lớp và các hành động mà một lớp có thể thực hiện.
Ký hiệu dấu chấm “.” trong C#
string greeting = "hello"; // Prints 5 Console.WriteLine(greeting.Length); // Returns 8 Math.Min(8, 920);
Trong C #, một thành viên của một lớp có thể được truy vấn bằng ký hiệu dấu chấm.
Class Instance trong C#
Burger cheeseburger = new Burger(); // If a class is a recipe, then an object is a single meal made from that recipe. House tudor = new House(); // If a class is a blueprint, then an object is a house made from that blueprint.
Trong C #, một đối tượng là Instance của một lớp. Một đối tượng có thể được tạo từ một lớp bằng cách sử dụng từ new
.
Field trong C#
public class Person { private string firstName; private string lastName; } // In this example, firstName and lastName are private fields of the Person class. // For effective encapsulation, a field is typically set to private, then accessed using a property. This ensures that values passed to an instance are validated (assuming the property implements some kind of validation for its field).
Trong C #, một trường (field) lưu trữ một phần dữ liệu trong một đối tượng. Nó hoạt động giống như một biến và có thể có một giá trị khác nhau cho mỗi trường hợp của một kiểu.
Một field có thể được sử dụng bởi các lệnh: public
, private
, static
, và readonly
. Nếu không có lệnh nào truy vấn, một field được mặc định là private
.
Thuộc tính (Property) trong C#
public class Freshman { private string firstName; public string FirstName { get { return firstName; } set { firstName = value; } } } public static void Main (string[] args) { Freshman f = new Freshman(); f.FirstName = "Louie"; // Prints "Louie" Console.WriteLine(f.FirstName); } // In this example, FirstName is a property
Trong C #, thuộc tính là một thành viên của đối tượng kiểm soát cách một trường có thể được truy cập và / hoặc sửa đổi. Thuộc tính xác định hai phương thức: phương thức get()
mô tả cách một trường có thể được truy cập và phương thức set()
mô tả cách một trường có thể được sửa đổi.
Một trường hợp sử dụng cho thuộc tính là kiểm soát quyền truy cập vào một trường. Cách khác là xác thực các giá trị cho một trường.
Triển khai thuộc tính tự động trong C#
public class HotSauce { public string Title { get; set; } public string Origin { get; set; } } // In this example, Title and Origin are auto-implemented properties. Notice that a definition for each field (like private string title) is no longer necessary. A hidden, private field is created for each property during runtime.
Trong C #, một thuộc tính được triển khai tự động đọc và ghi vào một trường riêng, giống như các thuộc tính khác, nhưng nó không yêu cầu định nghĩa rõ ràng cho các phương thức của trình truy cập cũng như trường. Nó được sử dụng với cú pháp { get; set; }
. Điều này giúp mã của bạn trở nên ngắn gọn hơn.
Constructor trong C#
// Takes two arguments public Forest(int area, string country) { this.Area = area; this.Country = country; } // Takes one argument public Forest(int area) { this.Area = area; this.Country = "Unknown"; } // Typically, a constructor is used to set initial values and run any code needed to “set up” an instance. // A constructor looks like a method, but its return type and method name are reduced to the name of the enclosing type.
Trong C #, bất cứ khi nào một instance của một lớp được tạo, phương thức khởi tạo của nó (constructor) sẽ được gọi. Giống như các phương thức, một hàm tạo có thể được nạp chồng. Nó phải có cùng tên với lớp bao quanh. Điều này hữu ích khi bạn muốn xác định một hàm tạo bổ sung có một số lượng đối số khác nhau.
“this” trong C#
// We can use the this keyword to refer to the current class’s members hidden by similar names: public NationalPark(int area, string state) { this.area = area; this.state = state; } // The code below requires duplicate code, which can lead to extra work and errors when changes are needed: public NationalPark(int area, string state) { area = area; state = state; } public NationalPark(int area) { area = area; state = "Unknown"; } // Use this to have one constructor call another: public NationalPark(int area) : this (state, "Unknown") { }
Trong C #, từ this
đề cập đến instance hiện tại của một lớp.
Hàm tạo không tham số trong C#
public class Freshman { public string FirstName { get; set; } } public static void Main (string[] args) { Freshman f = new Freshman(); // name is null string name = f.FirstName; } // In this example, no constructor is defined in Freshman, but a parameterless constructor is still available for use in Main().
Trong C #, nếu không có hàm tạo nào được chỉ định trong một lớp, trình biên dịch sẽ tự động tạo một hàm tạo không tham số.
“public” & “private” trong C#
public class Speech { private string greeting = "Greetings"; private string FormalGreeting() { return $"{greeting} and salutations"; } public string Scream() { return FormalGreeting().ToUpper(); } } public static void Main (string[] args) { Speech s = new Speech(); //string sfg = s.FormalGreeting(); // Error! //string sg = s.greeting; // Error! Console.WriteLine(s.Scream()); } // In this example, greeting and FormalGreeting() are private. They cannot be called from the Main() method, which belongs to a different class. However the code within Scream() can access those members because Scream() is part of the same class.
Trong C #, các thành viên của một lớp có thể được đánh dấu bằng các bổ ngữ truy cập, bao gồm public
và private
. public
là thành viên có thể được truy cập bởi các lớp khác. private
là thành viên chỉ có thể được truy cập bằng mã trong cùng một lớp.
Theo mặc định, các trường, thuộc tính và phương thức là private
và các lớp là public
.
Static trong C#
class Forest { static Forest() { Console.WriteLine("Type Initialized"); } } // In this class, either of the following two lines would trigger the static constructor (but it would not be triggered twice if these two lines followed each other in succession): Forest f = new Forest(); Forest.Define();
Trong C #, một hàm tạo Static được chạy một lần cho mỗi kiểu, không phải cho mỗi trường hợp. Nó phải là không tham số. Nó được gọi trước khi kiểu được khởi tạo hoặc một thành viên static được truy cập.
Static Class trong C#
//Two examples of static classes calling static methods: Math.Min(23, 97); Console.WriteLine("Let's Go!");
Trong C #, một lớp Static không thể được khởi tạo. Các thành viên của nó được truy cập bằng tên lớp.
Điều này hữu ích khi bạn muốn một lớp cung cấp một bộ công cụ nhưng không cần duy trì bất kỳ dữ liệu nội bộ nào.
Math
là một lớp Static thường được sử dụng.
Interfaces & Inheritance
Interface trong C#
interface IAutomobile { string LicensePlate { get; } double Speed { get; } int Wheels { get; } } // The IAutomobile interface has three properties. Any class that implements this interface must have these three properties. public interface IAccount { void PayInFunds ( decimal amount ); bool WithdrawFunds ( decimal amount ); decimal GetBalance (); } // The IAccount interface has three methods to implement. public class CustomerAccount : IAccount { } // This CustomerAccount class is labeled with : IAccount, which means that it will implement that interface.
Trong C #, một interface chứa các định nghĩa cho một nhóm các chức năng liên quan mà một lớp có thể triển khai.
Các interface rất hữu ích vì chúng đảm bảo cách một lớp hoạt động. Điều này, cùng với ý nghĩa là trong thực tế một lớp có thể triển khai nhiều interface, giúp tổ chức và mô-đun hóa các thành phần của phần mềm.
Cách tốt nhất để bắt đầu tên của interface bằng chữ cái “I”.
Tính kế thừa (Inheritance) trong C#
public class Honeymoon : TripPlanner { } // Similar to an interface, inheritance also uses the colon syntax to denote a class inherited super class. In this case, Honeymoon class inherits from TripPlanner class. // A derived class can only inherit from one base class, but inheritance is transitive. That base class may inherit from another class, and so on, which creates a class hierachy.
Trong C #, kế thừa là quá trình một lớp kế thừa các thành viên của lớp khác. Lớp kế thừa được gọi là lớp con hoặc lớp dẫn xuất. Lớp khác được gọi là lớp cha, hoặc lớp cơ sở.
Khi bạn định nghĩa một lớp kế thừa từ một lớp khác, lớp dẫn xuất mặc nhiên nhận được tất cả các thành viên của lớp cơ sở, ngoại trừ các hàm tạo và trình hoàn thiện của nó. Do đó, lớp dẫn xuất có thể sử dụng lại mã trong lớp cơ sở mà không cần phải triển khai lại nó. Trong lớp dẫn xuất, bạn có thể thêm nhiều thành viên hơn. Theo cách này, lớp dẫn xuất mở rộng chức năng của lớp cơ sở.
“protected” trong C#
public class BankAccount { protected decimal balance = 0; } public class StudentAccount : BankAccount { } // In this example, the BankAccount (superclass) and StudentAccount (subclass) have access to the balance field. Any other class does not.
Trong C #, một thành viên được bảo vệ có thể được truy cập bởi lớp hiện tại và bất kỳ lớp nào kế thừa từ đó. Điều này được chỉ định bởi lệnh protected.
“override/virtual” trong C#
class BaseClass { public virtual void Method1() { Console.WriteLine("Base - Method1"); } } class DerivedClass : BaseClass { public override void Method1() { Console.WriteLine("Derived - Method1");&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp;} }
Trong C #, một lớp dẫn xuất (lớp con) có thể sửa đổi hành động của một phương thức kế thừa. Phương thức trong lớp dẫn xuất phải được gắn nhãn override
và phương thức trong lớp cơ sở (lớp cha) phải được gắn nhãn virtual
.
virtual
và override
tương đối hữu ích bởi 2 lý do:
- Vì trình biên dịch xử lý các phương thức “thường” và virtual khác nhau, chúng phải được đánh dấu như vậy.
- Điều này tránh “ẩn” các phương thức kế thừa, giúp các nhà phát triển hiểu được ý định của mã.
“abstract” trong C#
abstract class Shape { public abstract int GetArea(); } class Square : Shape { int side; public Square(int n) =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; side = n; // GetArea method is required to avoid a compile-time error. public override int GetArea() =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; side * side; } // In this example, GetArea() is an abstract method within the abstract Shape class. It is implemented by the derived class Square.
Trong C #, công cụ sửa đổi abstract
chỉ ra rằng thứ đang được sửa đổi có phần triển khai bị thiếu hoặc không đầy đủ. Nó phải được thực thi hoàn toàn bởi một lớp dẫn xuất non-abstract.
Công cụ sửa đổi abstract
có thể được sử dụng với các lớp, phương thức, thuộc tính, chỉ mục và sự kiện. Sử dụng công cụ sửa đổi abstract
trong khai báo lớp để chỉ ra rằng một lớp chỉ được dự định là lớp cơ sở của các lớp khác, không được khởi tạo riêng.
Nếu ít nhất một thành viên của lớp là abstract
, thì lớp chứa cũng phải được đánh dấu là abstract
.
Việc thực hiện hoàn chỉnh một thành viên abstract
phải được đánh dấu override
.
Sự tham chiếu (References)
Loại tham chiếu trong C#
SportsCar sc = new SportsCar(100); SportsCar sc2 = sc; sc.SpeedUp(); // Method adds 20 Console.WriteLine(sc.Speed); // 120 Console.WriteLine(sc2.Speed); // 120 // In this code, sc and sc2 refer to the same object. The last two lines will print the same value to the console.
Trong C#, các class và interface là các kiểu tham chiếu. Các biến của kiểu tham chiếu lưu trữ các tham chiếu đến dữ liệu (đối tượng) của chúng trong bộ nhớ và chúng không chứa chính dữ liệu đó.
Một loại đối tượng như Object
, string
, hoặc dynamic
cũng là một loại tham chiếu.
Tham chiếu đối tượng trong C#
// Woman inherits from Human, which inherits from Animal, and it implements IPerson: class Human : Animal class Woman : Human, IPerson // All of these references are valid: Woman eve = new Woman(); Human h = eve; Animal a = eve; IPerson p = eve;
Trong C#, một đối tượng có thể được tham chiếu bởi bất kỳ kiểu nào trong hệ thống phân cấp kế thừa của nó hoặc bởi bất kỳ interface nào mà nó triển khai.
Chức năng tham chiếu đối tượng trong C#
Player p = new Player(); Fan f = p; p.SignContract(); f.SignContract(); // Error! 'SignContract()` is not defined for the type 'Fan'
Trong C#, chức năng có sẵn cho một tham chiếu đối tượng được xác định bởi loại của tham chiếu, không phải loại của đối tượng.
Tính đa hình (Polyphormism) trong C#
class Novel : Book { public override string Stringify() { return "This is a Novel!; } } class Book { public virtual string Stringify() { return "This is a Book!; } } // In the below code, you’ll see that a Novel and Book object can both be referred to as Books. This is one of their shared interfaces. At the same time, they are different data types with unique functionality. Book bk = new Book(); Book warAndPeace = new Novel(); Console.WriteLine(bk.Stringify()); Console.WriteLine(warAndPeace.Stringify()); // This is a Book! // This is a Novel // Even though bk and warAndPeace are the same type of reference, their behavior is different. Novel overrides the Stringify() method, so all Novel objects (regardless of reference type) will use that method.
Tính đa hình (Polymorphism) là khả năng trong lập trình trình bày cùng một interface cho các form nền tảng (kiểu dữ liệu) khác nhau.
Chúng ta có thể chia ý tưởng thành hai khái niệm liên quan. Một ngôn ngữ lập trình hỗ trợ tính đa hình nếu:
- Các đối tượng thuộc các loại khác nhau có một interface chung (interface theo nghĩa chung, không chỉ là interface của C #), và
- Các đối tượng có thể duy trì chức năng duy nhất cho kiểu dữ liệu của chúng
Upcasting trong C#
// In this case, string inherits from Object: string s = "Hi"; Object o = s; // In this case, Laptop implements the IPortable interface: Laptop lap = new Laptop(); IPortable portable = lap;
Trong C#, upcasting là tạo một lớp cha kế thừa hoặc một tham chiếu giao diện được triển khai từ một tham chiếu lớp con.
Downcasting trong C#
// Dog inherits from Pet. An implicit downcast throws a compile-time error: Pet pet = new Pet(); Dog dog = pet; // error CS0266: Cannot implicitly convert type `Pet` to `Dog`. An explicit conversion exists (are you missing a cast?) // Every downcast must be explicit, using the cast operator, like (TYPE). This fixes the compile-time error but raises a new runtime error. Pet pet = new Pet(); Dog dog = (Pet)pet; // runtime error: System.InvalidCastException: Specified cast is not valid. //The explicit downcast would only work if the underlying object is of type Dog: Dog dog = new Dog(); Pet pet = dog; Dog puppy = (Dog)pet;
Trong C#, downcasting là tạo một tham chiếu lớp con từ một lớp cha hoặc tham chiếu giao diện..
Downcasting có thể dẫn đến lỗi thời gian chạy nếu lớp cha không thể được truyền sang lớp con được chỉ định.
Account a = new Account(); CustomerAccount ca = a; // error CS0266: Cannot implicitly convert type `Account` to `CustomerAccount`. An explicit conversion exists (are you missing a cast?)
Tham chiếu rỗng (Null) trong C#
MyClass mc; //unassigned Console.WriteLine (mc == null); // error CS0165: Use of unassigned local variable 'mc' MyClass mc = null; //explicitly 'null' Console.WriteLine(mc == null); // Prints true. // Array of unassigned references MyClass[] objects = new MyClass[5]; // objects[0] is unassigned, objects[1] is unassigned, etc...
Trong C#, tham chiếu không xác định là tham chiếu rỗng (null) hoặc chưa được gán.Tham chiếu rỗng được đại diện bởi từ null
.
Hãy cẩn thận khi kiểm tra các tham chiếu rỗng và chưa được gán. C# chỉ có thể so sánh một tham chiếu rỗng nếu nó được gắn nhãn null
rõ ràng
Kiểu biến (giá trị) trong C#
Trong C#, các loại biến chứa chính dữ liệu. Bao gồm int
, bool
, char
, và double
.
Dưới đây là toàn bộ danh sách các loại biến:
char
,bool
,DateTime
- Tất cả kiểu dữ liệu số
- Cấu trúc (
struct
) - Bảng kê (
enum
)
So sánh trong C#
// int is a value type, so == uses value equality: int num1 = 9; int num2 = 9; Console.WriteLine(num1 == num2); // Prints true // All classes are reference types, so == uses reference equality: WorldCupTeam japan = new WorldCupTeam(2018); WorldCupTeam brazil = new WorldCupTeam(2018); Console.WriteLine(japan == brazil); // Prints false // This is because japan and brazil refer to two different locations in memory (even though they contain objects with the same values):
Trong C#, kiểu so sánh được thực hiện với toán tử bình đẳng (==
), khác với các loại tham chiếu và biến.
Khi hai loại biến được so sánh, chúng được so sánh để bình đẳng về giá trị. Chúng bằng nhau nếu chúng có cùng giá trị.
Khi hai loại tham chiếu được so sánh, chúng được so sánh để tham chiếu bình đẳng. Chúng bằng nhau nếu chúng đề cập đến cùng một vị trí trong bộ nhớ.
Ghi đè (Override) trong C#
// In the below example, DerivedClass.Method1() overrides BaseClass.Method1(). bcdc is a BaseClass-type reference to a DerivedClass value. Calling bcdc.Method1() invokes DerivedClass.Method1(). class MainClass { public static void Main (string[] args) { BaseClass bc = new BaseClass(); DerivedClass dc = new DerivedClass(); BaseClass bcdc = new DerivedClass(); bc.Method1(); dc.Method1(); bcdc.Method1(); } } class BaseClass { public virtual void Method1() { Console.WriteLine("Base - Method1"); } } class DerivedClass : BaseClass { public override void Method1() { Console.WriteLine("Derived - Method1"); } } // The above code produces this result: // Base - Method1 // Derived - Method1 // Derived - Method1 // If we wanted bcdc.Method1() to invoked BaseClass.Method1(), then we would label DerivedClass.Method1() as new, not override.
Trong C#, override
cho phép sửa đổi các tham chiếu class cơ sở bởi một class dẫn xuất để truy cập bằng các tham chiếu dẫn xuất.
Tức là: nếu một “class dẫn xuất” ghi đè lên một “class cơ sở”, thì phiên bản ghi đè có thể được truy cập bằng các tham chiếu “dẫn xuất” và tham chiếu “cơ sở”.
Object Class trong C#
// When you write this code: class Dog {} // C# assumes you mean: class Dog : Object {} //Even if your class explicitly inherits from a class that is NOT an Object, then some class in its class hierachy will inherit from Object. In the below example, Dog inherits from Pet, which inherits from Animal, which inherits from Object: class Dog : Pet {} class Pet : Animal {} class Animal {} //Since every class inherits from Object, any instance of a class can be referred to as an Object. Dog puppy = new Dog(); Object o = puppy;
Trong C#, “class cở sở” của tất cả các loại là Object
. Mọi class đều kế thừa class này một cách ngầm định.
Khi bạn tạo một class không có kế thừa, C# mặc định làm cho nó kế thừa từ Object
.
Phương thức Object Class trong C#
Object obj = new Object(); Console.WriteLine(obj.ToString()); // The example displays the following output: //&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; System.Object public static void Main() { MyBaseClass myBase = new MyBaseClass(); MyDerivedClass myDerived = new MyDerivedClass(); object o = myDerived; MyBaseClass b = myDerived; Console.WriteLine("mybase: Type is {0}", myBase.GetType()); Console.WriteLine("myDerived: Type is {0}", myDerived.GetType()); Console.WriteLine("object o = myDerived: Type is {0}", o.GetType()); Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetType()); } // The example displays the following output: //&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; mybase: Type is MyBaseClass //&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; myDerived: Type is MyDerivedClass //&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; object o = myDerived: Type is MyDerivedClass //&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; MyBaseClass b = myDerived: Type is MyDerivedClass
Trong C#, Object
class định nghĩa cho: ToString()
, Equals(Object)
, và GetType()
.
ToString() trong C#
Random r = new Random(); // These two lines are equivalent: Console.WriteLine(r); Console.WriteLine(r.ToString());
Khi một đối tượng không phải chuỗi được in ra bảng điều khiển với Console.WriteLine()
, thì sẽ sử dụng hàm để gọi ra là ToString()
So sánh chuỗi trong C#
//In this example, even if s and t are not referentially equal, they are equal by value: string s = "hello"; string t = "hello"; // b is true bool b = (s == t);
Trong C#, string
là một loại tham chiếu nhưng nó có thể được so sánh theo giá trị bằng cách sử dụng ==
.
Các loại chuỗi bất biến trong C#
// Two examples demonstrating how immutablility determines string behavior. In both examples, changing one string variable will not affect other variables that originally shared that value. //EXAMPLE 1 string a = "Hello?"; string b = a; b = "HELLLLLLLO!!!!"; Console.WriteLine(b); // Prints "HELLLLLLLO!!!!" Console.WriteLine(a); // Prints "Hello?" //EXAMPLE 2 string s1 = "Hello "; string s2 = s1; s1 += "World"; System.Console.WriteLine(s2); // Prints "Hello "
Trong C#, các kiểu string
là bất biến, có nghĩa là chúng không thể thay đổi sau khi chúng được tạo.
Chuỗi trống (Empty String) trong C#
// Empty string: string s1 = ""; // Also empty string: string s2 = String.Empty; // This prints true: Console.WriteLine(s1 == s2); // Unassigned: string s3; // Null: string s4 = null;
Trong C#, lệnh string
có thể tham chiếu đến chuỗi rỗng với ""
và String.Empty
.
Điều này tách biệt với null
và các tham chiếu chưa chỉ định, cũng có thể đặt kiểu string
.
Một số thuật ngữ phổ biến trong C#
Class (lớp)
Class trong các ngôn ngữ lập trình hướng đối tượng nói chung, trong C# nói riêng, mang ý nghĩa là một kiểu dữ liệu. Đối với C#, class là các khối xây dựng cơ sở của các chương trình ứng dụng, và là trung tâm của lập trình C#. Class trong C# là một loại kiểu dữ liệu đặc biệt chứa định nghĩa những thuộc tính (thông tin) và phương thức (hành vi), dùng để mô tả chung cho một nhóm những thực thể cùng loại.
Trong C#, mỗi class có thể chứa:
- Biến thành viên (field): Lưu trữ các thông tin mô tả về đối tượng hay trạng thái của đối tượng;
- Thuộc tính (property): có vai trò lưu trữ thông tin tương tự như biến thành viên nhưng có khả năng kiểm soát dữ liệu xuất nhập;
- Phương thức (method): Dùng để cập nhật, tính toán, cung cấp và xử lý thông tin;
- Sự kiện (delegate/event): Gửi thông báo về sự thay đổi trạng thái của đối tượng ra bên ngoài.
- Định nghĩa của kiểu dữ liệu khác, gọi là kiểu thành viên (member /inner/nested type). Class có thể chứa định nghĩa của bất kỳ nhóm kiểu nào mà bạn đã biết (class, struct, interface, delegate, enum).
Khi xem class như một kiểu dữ liệu thì object của class tương ứng chính là biến thuộc kiểu dữ liệu đó. Class chứa mô tả trừu tượng còn object chứa giá trị cụ thể của mỗi mô tả đó.
Reference (tham chiếu)
Tham chiếu là một giá trị cho phép chương trình truy xuất gián tiếp tới một số liệu cụ thể, như một biến hay một bản ghi, trong bộ nhớ máy tính hay trong các thiết bị lưu trữ khác. Quá trình mà tham chiếu chỉ đến (refer) dữ liệu, và truy xuất dữ liệu được gọi là tham chiếu ngược (dereferencing) đến tham chiếu.
Một tham chiếu thì khác với chính dữ liệu đó. Thường thì, để tham chiếu đến dữ liệu chứa trong bộ nhớ của một hệ thống nhất định, một tham chiếu được hiện thực như là địa chỉ vật lý của nơi mà dữ liệu được chứa trong bộ nhớ hay trong thiết bị lưu trữ. Vì lý do này, tham chiếu thường bị nhầm lẫn một cách sai lệch với con trỏ hay địa chỉ vùng nhớ, và được nói là “trỏ đến” (point to) dữ liệu.
Type (kiểu, loại)
Kiểu dữ liệu (data type, hay đơn giản là type) trong C# (cũng tương tự như các ngôn ngữ khác) là một đặc tính của dữ liệu nhằm thông báo cho trình biên dịch C# biết về ý định sử dụng dữ liệu của lập trình viên. Một trong những việc đầu tiên cần sử dụng đến kiểu dữ liệu là khai báo biến và hằng mà chúng ta đã biết. C# nghiêm ngặt hơn nhiều so với các ngôn ngữ khác về vấn đề kiểu dữ liệu.
Object (đối tượng)
Đối tượng (object) là một thực thể trong thế giới thực, ví dụ như cái bàn, cây viết, điện thoại, chiếc xe hơi …. Nó là một thực thể có trạng thái và hành vi. Ở đây, trạng thái có nghĩa là dữ liệu và hành vi có nghĩa là phương thức. Nó là một thực thể runtime, vì nó được tạo ra trong thời gian chương trình chạy. Đối tượng là một thể hiện của một lớp. Tất cả các thành viên của lớp có thể được truy cập thông qua đối tượng
String (chuỗi)
Trong C#, chuỗi (string) là một chuỗi các ký tự Unicode hoặc mảng các ký tự. Phạm vi các ký tự Unicode bắt đầu từ U +0000 đến U +FFFF. Mảng các ký tự được gọi là text, vì vậy chuỗi là đại diện của text. Chúng ta hay bị nhầm lẫn và hay hiểu rằng chuỗi (string) là một từ khóa hay đối tượng, lớp.
Chuỗi được đại diện bởi lớp System.String. Từ khóa “string” là một bí danh của lớp System.String. Thay vì viết System.String, người ta có thể sử dụng là String, là viết tắt của lớp System.String. Về cơ bản, string và String đều có thể được sử dụng như một bí danh của lớp System.String. Vì vậy chuỗi là một đối tượng của lớp System.String.
Interface
Một Interface được định nghĩa như là một giao ước có tính chất cú pháp (syntactical contract) mà tất cả lớp kế thừa Interface đó nên theo. Interface định nghĩa phần “là gì” của giao ước và các lớp kế thừa định nghĩa phần “cách nào” của giao ước đó.
Interface định nghĩa các thuộc tính, phương thức và sự kiện, mà là các thành viên của Interface đó. Các Interface chỉ chứa khai báo của các thành viên này. Việc định nghĩa các thành viên là trách nhiệm của lớp kế thừa. Nó thường giúp ích trong việc cung cấp một Cấu trúc chuẩn mà các lớp kế thừa nên theo.
Value (biến, giá trị)
Một biến là không gì khác ngoài một tên được cung cấp cho khu vực lưu giữ mà chương trình có thể thao tác. Mỗi biến trong C# có một kiểu cụ thể, mà quyết định kích cỡ và cách bố trí bộ nhớ của biến đó, cách dãy giá trị có thể được lưu giữ trong bộ nhớ đó, và cách tập hợp các hoạt động có thể được áp dụng tới biến đó.
Trên đây, MESIDAS đã chia sẻ cho các bạn những câu lệnh, những cú pháp trong C# (C Sharp) và kèm theo đó có cả những ví dụ cũng như là giải thích rõ ràng. Chúng tôi hy vọng rằng, với những kiến thức được chia sẻ trong bài viết này sẽ giúp ích cho các bạn trong quá trình tìm hiểu, nghiên cứu, học tập và làm việc với ngôn ngữ lập trình C# (C Sharp) này. Xin cảm ơn!
Nguồn tham khảo chính: https://www.codecademy.com/learn/learn-c-sharp/