2011-07-01 29 views
5

Các phương thức mở rộng được triển khai bên trong như thế nào? Tôi có nghĩa là những gì sẽ xảy ra khi trình biên dịch thấy một khai báo cho một phương thức mở rộng và những gì xảy ra khi chạy khi có một lời gọi đến một phương thức mở rộng.Cách thức thực hiện các phương thức mở rộng trong nội bộ

Phản ánh có liên quan không? Hoặc khi bạn có một phương thức mở rộng là mã của nó được tiêm trong siêu dữ liệu kiểu lớp đích với một số cờ bổ sung lưu ý rằng đây là một phương thức mở rộng và sau đó CLR biết cách xử lý nó?

Vì vậy, nói chung, điều gì xảy ra dưới mui xe?

Trả lời

6

Như đã được các đồng nghiệp khác nói, đó chỉ là phương pháp tĩnh. Đó là tất cả về trình biên dịch chúng ta có thể nói rằng CLR thậm chí không có ý tưởng về các phương pháp mở rộng. Bạn có thể thử để kiểm tra mã IL ..

Dưới đây là một ví dụ

static class ExtendedString 
{ 
    public static String TestMethod(this String str, String someParam) 
    { 
     return someParam; 
    } 
} 

static void Main(string[] args) 
{ 
    String str = String.Empty; 
    Console.WriteLine(str.TestMethod("Hello World!!")); 
    ........ 
} 

Và đây là mã IL.

IL_0001: ldsfld  string [mscorlib]System.String::Empty 
    IL_0006: stloc.0 
    IL_0007: ldloc.0 
    IL_0008: ldstr  "Hello World!!" 
    IL_000d: call  string StringPooling.ExtendedString::TestMethod(string, 
                     string) 
    IL_0012: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_0017: nop 

Như bạn có thể thấy đây chỉ là cuộc gọi phương pháp tĩnh. Phương thức này không được thêm vào lớp, nhưng trình biên dịch làm cho nó trông như thế. Và trên lớp phản chiếu sự khác biệt duy nhất bạn có thể thấy là CompilerServices.ExtensionAttribute được thêm vào.

4

Phương thức mở rộng được chuyển đổi thành các hàm tĩnh. Nói cách khác, Chúng là đường cú pháp cho các hàm tĩnh.

2

Tôi không nghĩ rằng reflection có liên quan đến các phương pháp mở rộng. Phương pháp mở rộng được xử lý giống như cách bạn viết static helper function trong một helper class, khác biệt duy nhất là trình biên dịch thực hiện nó cho bạn.

1

Để làm rõ câu trả lời ở trên ... Các phương pháp mở rộng là các hàm tĩnh. Các tính năng bổ sung trong .NET 3.5 cho phép chúng được hiểu như thể chúng là các phương thức mới trên kiểu được đề cập.

0

Phương pháp mở rộng chỉ là phương pháp tĩnh. Sự khác biệt duy nhất được đưa ra bởi các công cụ như trình soạn thảo Visual Studio mà bật lên cho các tính năng tự động hoàn thành (intellisense). Bạn có thể tìm thấy giải thích chi tiết tại đây: C# Extension Methods: Syntactic Sugar or Useful Tool?

0

Phương pháp mở rộng rất giống với phương pháp static với sự khác biệt duy nhất trong thuộc tính này là một phương thức Tiện ích mở rộng.

Bạn có thể read this

0

Có, phương pháp mở rộng chỉ là phương pháp tĩnh. Họ không có thêm đặc quyền nào đối với các lớp mà họ cho là "mở rộng". Tuy nhiên, trình biên dịch không đánh dấu phương thức tĩnh "mở rộng" với một ExtensionAttribute. Bạn có thể thấy điều này trong IL. Điều này làm cho trình biên dịch xử lý nó đặc biệt, do đó bạn không thể thực sự gọi nó như một phương thức tĩnh thông thường. Ví dụ: thao tác này sẽ không biên dịch:

var test = new [] { "Goodbye", "Cruel", "World" }; 
var result = IEnumerable<string>.Where<string>(test, s => s.Length > 5); 

Mặc dù đây là những gì xảy ra dưới mui xe.

Nhưng như LukeH lưu ý bên dưới, bạn có thể gọi nó trên lớp nơi nó thực sự được xác định ... Silly me.

+0

Bạn có thể gọi trực tiếp các phương thức mở rộng dưới dạng phương thức tĩnh, chỉ là phương thức tĩnh trên một lớp tĩnh khác: 'var result = Enumerable.Where (test, s => s.Length> 5);' – LukeH

+0

You ' hoàn toàn đúng. Nó không có ý nghĩa để cố gắng gọi nó ra khỏi loại bạn đang "mở rộng". Lỗi của tôi. – Einar

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