2011-12-29 26 views
8

Tôi có một câu hỏi liên quan đến các cuộc gọi phương pháp sau đây:Generic đường cú pháp hoặc cải thiện đúng

var ctl1 = this.FindControlRecursively("SomeField") as HiddenField; 
var ctl = this.FindControlRecursively<HiddenField>("SomeField"); 

Dưới đây là IL cho hai cuộc gọi sau đây:

IL_0010: ldstr  "AsyncReset" 
IL_0015: call  class [System.Web]System.Web.UI.Control [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively(class [System.Web]System.Web.UI.Control,string) 

IL_001a: isinst  [System.Web]System.Web.UI.WebControls.HiddenField 
IL_001f: stloc.0 
IL_0020: ldarg.0 
IL_0021: ldstr  "AsyncReset" 
IL_0026: call  !!0 [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively<class [System.Web]System.Web.UI.WebControls.HiddenField>(class [System.Web]System.Web.UI.Control,string) 

Tôi đã luôn luôn nghĩ rằng trong tình huống này, phiên bản chung của phương pháp này là nhiều hơn "cú pháp đường" so với cải tiến thực sự. IL có kể một câu chuyện khác không?

Trả lời

8

Generics được tích hợp vào C#, vì vậy nó là một "cải tiến thực sự". Do đó tại sao có thể thay đổi phương sai đồng thời và phương sai tương phản, cũng như phản ánh trên các kiểu generic và tạo các kiểu generic dựa trên sự phản chiếu (chẳng hạn như List<T> trong đó T được xác định tại thời gian chạy).

Điều này khác với C++, trong đó nhiều mẫu, theo nhiều cách, đường cú pháp. Trình biên dịch thực sự tạo mã cho mỗi loại chung bạn sử dụng - vì vậy Add<T> sẽ tạo Add<int>, Add<long>, Add<short>, Add<MyClass>, v.v. nếu bạn đang sử dụng các chức năng đó và tương tự cho các lớp học. Lợi ích của việc này chủ yếu là các toán tử và một vài thứ nhỏ hơn - nếu mỗi loại có toán tử + và Add<T>(T a, T b) trả về + b, tất cả các loại sẽ hoạt động tốt. Trình biên dịch của C# sẽ phàn nàn vì nó không thể/không giải quyết khai báo toán tử cho bất kỳ kiểu nào và tất cả ở thời gian biên dịch. Hơn nữa, C# (không chắc chắn 100%, nhưng có thể 90%) tạo ra 1 kiểu thực thi chung cho các kiểu tham chiếu (nếu bạn đang sử dụng nó) và 1 cho mỗi kiểu giá trị (vì vậy int, long, Decimal, MyStruct, etc all được triển khai của riêng họ, nếu cần).

Các vấn đề liên quan