C# 3.0 (C# 2008)

Những cái mới trong C# .NET 3.0

Một số bạn hỏi tôi rằng có phải C# 3.0 nằm trong .NET 3.0 Framework hay không? Xin thưa là không? Mà C# 3.0 được giới thiệu trong .NET 3.5. [Xem thêm ở đây]

Trong C# 3.0 có một số tính năng mới đã được giới thiệu, dưới đây là liệt kê tóm tắt các tính năng đó:

  • Khai báo biến kiểu không tường minh (Implicitly typed local variables)
  • Tạo kiểu (lớp) tạm thời (Anonymous types)
  • Các phương thức mở rộng (Extension methods)
  • Khởi tạo các Object và Collection (Object and collection initializers)
  • Biểu thức Lambda (Lambda expressions)
  • Biểu thức truy vấn LINQ (Query expressions)
  • Biểu thức cây (Expression Trees)
  • Tự động xây dựng Properties (Auto-Implemented Properties)

Nội dung dưới đây sẽ đi sâu chi tiết vào một số các tính năng mới này.

Implicitly Typed Local Variables

C# 3.0 đưa thêm 1 từ khoá mới gọi là “var“. Từ khoá var cho phép định nghĩa 1 biến mà không cần khai báo kiểu tường minh, như ví dụ dưới đây là hợp lệ trong C# 3.0

var i = 1;

Một điểm lưu ý khi sử dụng khai báo này là giá trị gán vào phải được thực hiện ngay sau lệnh khai báo. Khi thực hiện lệnh gán thì biến đã được ngầm định khai báo kiểu tương ứng. Trong ví dụ:

var i = 1; // Correct
var i; //Incorrect

thì dòng lệnh thứ nhất khai báo là hợp lệ, và i được hiểu là kiểu int. Nhưng đối với dòng lệnh thứ 2, thì không được chấp nhận. Ngoài ra, kiểu dữ liệu được gán vào cũng không được là kiểu null.

Nếu ai đã từng sử dụng VB6 thì cũng lưu ý, đây không phải là kiểu Object cũng không phải là kiểu variant.

Đối với khởi tạo các kiểu dữ liệu mảng, thì có thể sử dụng syntax hơi khác một chút như ví dụ:

var intArr = new[] { 1, 2, 3, 4 };// Declare an array

Dòng code trên có thể được hiểu là intArr as int[];

Ngoài ra, var còn dùng để khai báo các biến có kiểu dùng tạm (Anonymous Types) sẽ được làm rõ trong phần kế tiếp.

Anonymous Types

C# 3.0 cho phép tạo ra các class dùng tạm thời mà không cần phải định nghĩa class đó trước. Ví dụ, mình cần 1 class tạm thời dùng để khai báo 1 mẫu xe có các thuộc tính là năm SX (manf), màu sắc (color) và số chỗ ngồi (seats) thì dưới đây là 1 ví dụ cho phép khai báo như vậy:

var mycar = new { manf = 2007, color = System.Drawing.Color.Black, seats = 4 };
mycar.manf = 2006;
mycar.color = System.Drawing.Color.White;

Trong dòng code trên, từ khoá new cho phép định nghĩa ra 3 thuộc tính là manf, color và seats. Khi compile, C# Compiler sẽ tạo ra 1 class tương tự vậy

class __Anonymous1 {

private int _manf = 2007;
private int _seats = 4;
private System.Drawing.Color _color = System.Drawing.Color.Black;
public string manf
{
get { return _manf; }
set { _manf = value; }
}

public string seats
{
get { return _seats; }
set { _seats = value; }
}

public int color
{
get { return _color; }
set { _color = value; }
}

}

Ngoài ra, nếu như có 1 khai báo khác tương tự để tạo 1 instances mới cho 1 class kiêủ như vậy, thì C# Compiler cũng đủ thông minh để tạo ra 1 class cho >2 khai báo như vậy, và thậm chí, trong code, có thể gán giá trị cho nhau (vì chung 1 type)

Extension Methods

Extension Method là 1 tính năng rất hay trong C# 3.0 này.

Giả sử bạn có được 1 class từ đâu đó, tuy nhiên, bạn không có code mà chỉ có file dll mà thôi. Bạn muốn mở rộng và thêm 1 số hàm của class MyPoint chẳng hạn, thì thông thường bạn sẽ làm cách nào? Inherit , viết Wrapper …?

Với Extension methods, thì C# cho phép lập trình viên viết các method cho các lớp khác một cách khá dễ dàng. Hãy xem ví dụ sau, class MyPoint là 1 class không có sẵn source, và mình muốn thêm 1 hàm để tính Distance giữa 2 điểm (2 object MyPoint) là từ chính MyPoint đang xét tới 1 MyPoint khác.

Rất đơn giản, khai báo 1 class khác và khai báo thêm hàm cần thêm vào, lưu ý từ khoá this trong Parameter đầu tiên

public static class MyExtend{

public static int DistanceTo(this MyPoint mp, MyPoint another){

//Process the method here
return (mp.x + mp.y) – (another.x + another.y);

}

}

Và trong lớp cần sử dụng… (trong ví dụ sau có dùng 1 tính năng mới của C# 3.0 là Object, Collection Initilizers sẽ được bàn sau)

List<MyPoint> allPoints = new List<MyPoint>{

new MyPoint{x = 1, y=2},
new MyPoint{x = 3, y=4},
new MyPoint{x = 4, y=2},
new MyPoint{x = 2, y=5}
};

int result = allPoints[1].DistanceTo(allPoints[2]);

Từ ví dụ trên, có thể thấy hàm DistanceTo được xem như 1 hàm của lớp MyPoint.

Khi sử dụng tính năng này, cần lưu ý:

  1. Hàm cần thêm vào phải là hàm static
  2. Hàm cần thêm vào phải đặt vào trong 1 class static
  3. Kiểu dữ liệu của tham số đầu tiên sẽ tương ứng với kiểu dữ liệu cần thêm vào.
  4. Từ khoá this phải đặt ở tham số đầu tiên
  5. Để sử dụng, thì class dùng để khai báo phải visible trong context cần sử dụng (dùng using…)

Object and Collection Initializers

C# 3.0 cũng cho phép khởi tạo các đối tượng và khai báo chỉ trong cùng 1 câu lệnh, và class cũng không cần phải có các constructor, hãy xem ví dụ khai báo Class MyPoint dưới đây:

public class MyPoint{

int _x = 0;
public int x {

get { return _x; }
set { _x = value; }

}

int _y = 0;
public int y{

get { return _y; }
set { _y = value; }

}

}

Lưu ý là ở đây, Minh không khai báo bất kỳ Constructor nào. Hãy xem ví dụ ở trên về Extension Method, C# 3.0 cho phép viết khởi tạo các class như đã được nêu ở bên trên

Đơn giản hơn:

MyPoint p = new MyPoint() { x = 1, y = 4 };

Cũng đã có câu hỏi rằng tại sao không gọi vậy cho lẹ:

MyPoint p = new MyPoint(1,4);

Do ở đây không sử dụng Constructor, nên cách gọi này là gọi 1 constructor với 2 tham số 1 và 2…

Auto-Implemented Properties

Trong lúc lập trình, việc khai báo các Properties cho 1 class là chuyện làm rất thường xuyên, như ví dụ ở trên, class MyPoint được khai báo các properties như sau

public class MyPoint{

int _x = 0;
public int x {

get { return _x; }
set { _x = value; }

}

int _y = 0;
public int y{

get { return _y; }
set { _y = value; }

}

}

Đa số các Properties đều thực hiện các thao tác như là ghi và đọc từ 1 biến private nào đó. Trong C# 3.0, nếu như properties của bạn chỉ thực hiện các thao tác như ở trên (đọc và ghi vào biến private) thì không cần phải khai báo như vậy, mà thay vào đó chỉ cần khai báo:

public class MyPoint{

public int x {get ; set;}

public int y {get ; set; }

}

Khi biên dịch, thì C# Compiler sẽ tự động tạo ra các biến private tương tự y như khai báo tường minh ở khai báo trên. Kết quả là 2 khai báo hoàn toàn tương tự nhau.

3 tính năng còn lại bữa sau viết tiếp vô đây, hết giờ … làm rồi

2 thoughts on “C# 3.0 (C# 2008)

Để lại phản hồi