Những chức năng mới của C# 2010

Khi quyển sách này đang được viết, thì phiên bản mới nhất của Microsoft là Visual Studio 2010 Beta 2 và .NET Framework 4.0 Beta 2 đang được giới CNTT tải về để nghiên cứu. Bắt đầu từ ngày 11/02/2010 sắp tới, Microsoft tổ chức những hội nghị mở rộng tại nhiều thành phố lớn trên toàn thế giới để giới thiệu phiên bản mới nhất của Visual Studio và .NET Framework, sẽ được tung ra thị trường vào ngày 22/03/2010.

Thứ nhất, vì phiên bản Visual Studio-2010 chưa được tung ra thị trường, cho nên những chức năng mới của Visual Studio-2010 được viết trong sách này, đều chưa được chính thức công nhận, và có thể có những thay đổi. Tuy nhiên, có thể nói rằng, sẽ không có bất cứ một thay đổi quan trọng nào có thể xảy ra.

Thứ hai, mặc dầu phiên bản mới sắp được phát hành, tất cả những tư liệu dẫn chứng cho những mã nguồn, cũng như những mã nguồn mẫu trong quyển sách này, vẫn là những gì nồng cốt nhất cho một lập trình C#, ngày hôm nay, cũng như sau khi Visual Studio-2010 được phát hành, và chắc chắn rằng vẫn còn là những nồng cốt của một chương trình C# cho tới phiên bản kế tiếp sau phiên bản Visual Studio-2010.

Những chủ đề (themes) của phiên bản C# mới.

Với phiên bản Visual Studio-2010, để có thể thống nhất về con số của những phiên bản, C# 2010 được gọi là C# 4.0, cùng một hệ số với phiên bản .NET Framework 4.0. Do đó, các bạn nên bắt đầu làm quen với cách gọi này: C# 4.0, thay vì C#-2010.

Chủ đề chính được Microsoft hoạch định cho phiên bản C# 4.0 là “Năng Động (Dynamic)”. Tất cả những chức năng mới của phiên bản C# 4.0 đều được phát triển chung quanh hai chữ “năng động”. Và như các bạn đã được biết, lớp đối tượng nền của tất cả các lớp đối tượng trong một lập trình C# là System.Object. Do đó, System.Object bắt buộc phải trở thành một lớp đối tượng có tính năng động. Nói một cách khác, mục tiêu của Microsoft cho phiên bản .NET Framework 4.0 nói chung, và C# nói riêng, là C# phải trở thành một ngôn ngữ có những lớp đối tượng năng động

Nhưng thế nào là lớp đối tượng năng động? Một lớp đối tượng năng động là một lớp đối tượng mà cấu trúc(structure) và trạng thái (behavior) của nó không bị bó buộc hoặc lệ thuộc vào những trạng thái tĩnh (static). Nói một cách khác, một đối tượng lớp không cần phải định nghĩa trước khi khởi tạo, mà có thể được định nghĩa khi bắt đầu khởi tạo trong lúc phần mềm đang vận hành. Và nói một cách khác nữa, một lớp đối tượng năng động là một lớp đối tượng mà biên trình (csc.exe) không biết một tí gì về đối tượng đó khi biên lập.

Những đối tượng (objects) dưới đây là những điển hình của một đối tượng năng động

• Đối tượng của những ngôn ngữ lập trình năng động, như Pyphon hoặc Ruby.
• Những đối tượng COM được truy cập qua giao ước IDispatch.
• Những dạng đối tượng nguyên thuỷ của .NET có thể truy cập qua phép đối xứng (reflection).
• Những đối tượng có cấu trúc thay đổi trong khi vận hành, như HTML DOM.

Mặc dầu thế, C# vẫn là một ngôn ngữ nặng tích chất không thay đổi (static), nhưng có khả năng tạo lên được những lớp đối tượng năng động.

Chủ đề thứ hai, hay mục tiêu thứ hai cho C#, là “cùng tiến hóa” với Visual Basic. Cùng tiến hóa, nhưng vẫn giữ những đặc tính riêng biệt. Nói một cách khác, 2 ngôn ngữ sẽ cùng có chung những chức năng và hiệu năng, nhưng vẫn là 2 ngôn ngữ riêng biệt với những cú pháp riêng biệt.

Những chức năng mới của C# được chia ra làm 4 thành phần, như sau:

1. Truy vấn năng động (dynamic lookup)
2. Tham số tên và tham số tuỳ chọn (Named and option parameters)
3. Chức năng giao tiếp với những COM đã được lựa chọn
4. Biến dạng (variance)


Truy vấn năng động (dynamic lookup)
Truy vấn năng động là những chức năng có thể tạo dựng được những hàm, những toán tử và chỉ mục, những thuộc tính và trường truy cập, và những đối tượng sự-tác có thể vượt qua những quy tắc đòi hỏi chỉ định dạng trước khi được khởi tạo.

Truy vấn năng động cho phép một phần mềm có thể kích hoạt được những đối tượng trong lúc vận hành mà không phải lưu tâm đến việc những đối tượng đó thuộc về những dạng nào, và từ đâu tới( COM, HTML DOM, Python, hoặc đối xứng). Chỉ cần áp dụng những thao tác xử lý vào một đối tượng, và để cho bộ vận hành thẩm định những thao tác đó.

Chức năng này cho các bạn sự uyển chuyển và giản dị hóa mã nguồn trong một thảo chương, nhưng đổi lại, dạng của một đối tượng không được thẩm định trong những thao tác truy vấn. Lớp đối tượng năng động không được thẩm tra khi biên lập, do đó, nếu có những lỗi lầm, những lỗi lầm đó chỉ xảy ra khi vận hành. Nói một cách khác, phần mềm của các bạn có nhiều hy vọng bị treo trong khi vận hành. Thông thường, khi phần mềm bị treo vì những lý do có liên quan đến việc xử lý của một đối tượng năng động, sẽ không có gì tổn hại đến hệ điều hành. Nhưng đôi khi, những lỗi lầm này có thể ảnh hưởng đến tính chất bảo vệ hệ thống phần mềm. Do đó, C# cho các bạn có sự tùy chọn giữa năng động và không năng động trước khi khởi tạo một đối tượng.

Dạng năng động (dynamic type)

Với C# 4.0, một dạng tĩnh có thể định dạng năng động. Với dạng tĩnh năng động, các bạn có thể tạo dựng những thao tác với những điều kiện chỉ có thể có trong lúc vận hành:

Code:
Code:
Dynamic năngĐộng=GetDynamicObject(...);
năngĐộng.M(7);
Với 2 hàng mã nguồn mẫu trên, biên trình csc.exe không thể thẩm định tên và những tham số thuộc đối tượng năngĐộng trên. Do đó, các bạn có thể dùng bất cứ tên (cho thuộc hàm) gì, và bất cứ một tham số nào. Khi phần mềm được vận hành, bộ vận hành DLR mới có thể thẩm định năngĐộng thuộc đối tượng gì. năngĐộng có thuộc hàm M() không, và thuộc hàm năngĐộng.M() có phải là một thuộc hàm có một tham số thuộc dạng số không.

Các bạn có thể gán bất cứ một giá trị nào cho một đối tượng năng động, và một đối tượng năng động cũng có thể gán cho bất cứ một dạng đối tượng nào, như sau:

Code:
Code:
class Program
{
    static void Main(string[] args)
    {
        dynamic d=199;
        int i=d;
        string str=d;
        Form frm=d;
    }
}
Vận hành năng động

Không những chỉ có thuộc hàm có thể...năng động, mà tất cả những gì thuộc về truy cập đều có thể năng động, kể cả uỷ nhiệm:

Code:
Code:
dynamic d=199;
d.f=d.P; // truy cap thuoc tinh
d["Hai]=d["Ba]; // truy van / cap nhat voi chi muc
int i=d + 3; // dung toan tu
string s=d(5,7); // Goi nhu mot uy nhiem
Khi vận hành, thao tác xử lý năng động được kích hoạt tuỳ theo tính tự nhiên của những đối tượng năng động dưói đây:

Đối tượng COM

Nếu đối tượng năng động là một đối tượng được định nghĩa từ một linh kiện COM, những thao tác xử lý được gửi qua IDispatch của đối tượng COM đó. Điều này cho phép chương trình gọi những hàm của nhiều dạng COM không có PIA (Primary Interop Assembly), và lệ thuộc vào những chức năng của COM không có trong ngôn ngữ C#, chẳng hạn như thuộc tính chỉ mục, hoặc thuộc tính mặc định.

Đối tượng năng động (dynamic objects)

Nếu đối tượng năng động là một đối tượng năng động thuộc dạng IDynamicObject, thao tác xử lý sẽ được khởi động tại tầng đối tượng. Do đó, một đối tượng định dạng IDynamicObject có thể hoàn toàn thay đổi phương tiện của những thao tác vận hành. Điều này rất thông dụng trong những ngôn ngữ năng động như IronPython hoặc IronRuby. Đối tượng thuộc dạng IDynamicObject còn có thể được dùng bởi HTML DOM.

Đối tượng lớp thuộc về .NET

Nếu không thuộc 2 đối tượng trên, thì đó là một đối tượng lớp .NET thông thường, và những thao tác xử lý được vận hành bằng cách dùng đối xứng (reflection) trên dạng lớp của đối tượng (để tìm ra những dẫn chứng), thí dụ như:

Code:
Code:
public void DoiTuongNangDongNET()
{
    dynamic d1=new TiepThiVien(“TT001”);
    dynamic d2=new NhanCong(“NC001”);
    string s;
    d1.M(s, d2, 3, null);
}
Vì hàm M() được gọi từ tầng đối tượng dynamic, biên trình sẽ không thẩm định ngữ nghĩa của hàm M(), mà chỉ lưu giữ thông tin M(2,d2,3,null) cho đến khi vận hành, nhường quyền thẩm định cho bộ vận hành DLR của .NET. Những thông tin này chủ yếu có những ý nghĩa như sau:

“Khởi động hàm M() với những tham số”:
1. Chuỗi ký tự
2. đối tượng năng động (d2)
3. hằng số 3
4. null

Khi vận hành, vì d1 không phải là một đối tượng COM, cũng không được định dạng IDynamicObject, nên bộ vận hành dùng phép đối xứng để truy vấn những dẫn chứng của đối tượng d1 như sau:

• Phép đối xứng được dùng để lấy thông tin về 2 đối tượng d1 và d2 và biết được d1 thuộc dạng TiepThiVien, và d2 thuộc dạng NhanCong.
• Tìm thuộc hàm M() có dấu ký (string, NhanCong, int, object).
• Nếu tìm thấy thuộc hàm, M() sẽ được kích hoạt. Nếu không, lỗi sẽ được ném về hàm DoiTươngNangDongNET().

Lý giải cho những tham số thuộc dạng dynamic (năng động)

Ngay cả trường hợp đối tượng nhận được hàm gọi là một đối tượng thuộc dạng lớp đã được định nghĩa, thông tin về hàm được gọi vẫn được lý giải khi vận hành. Điều này xảy ra nếu hàm được gọi có một hay nhiều tham số thuộc dạng dynamic:

Code:
Code:
public void DoiTuongNangDongNET()
{
    TiepThiVien d1=new TiepThiVien(“TT001”);
    dynamic d2=new NhanCong(“NC001”);
    string s;
    d1.M(s, d2, 3, null);
}
Trong hàm mẫu trên, tuy d1 là một đối tượng lớp thuộc dạng TiepThiVien, nhưng thuộc hàm M() của nó có một tham số được định với dạng dynamic. Do đó, kết quả vẫn là một dạng năng động, và sẽ được biên lập để được xử lý bởi bộ vận hành DLR theo mô hình năng động.
Những giới hạn của việc dùng đối tượng năng động
Bộ vận hành DLR có những giới hạn dưới đây:

• Đối tượng năng động có thể được khởi tạo cho một dạng lớp, nhưng C# 4.0 vẫn chưa có những cú pháp hổ trợ cho việc này.
• Bộ vận hành DLR không có khả năng tìm thấy những hàm nới rộng. Do đó, chương trình sẽ gặp lỗi vận hành nếu gọi hàm nới rộng trên một tầng đối tượng năng động.
• Hàm vô danh không thể dùng như một tham số khi gọi một hàm trên tầng đối tượng năng động.