2011-11-05 71 views
9

Tôi đọc một vài bài báo nói rằng với việc giới thiệu các đối số được đặt tên trong C# 3.0, tên của các tham số bây giờ là một phần của hợp đồng công khai. Điều này có đúng không, và điều đó có nghĩa là gì? Tôi chạy một thử nghiệm đơn giản và thay đổi tên tham số trong MyLib.dll không phá vỡ MyApp.exe gọi phương thức bằng cách sử dụng đối số đã đặt tên với tên gốc, tôi nghĩ vì trình biên dịch C# đã làm quá tải ở thời gian biên dịch và IL không biết gì về tên tham số. Đây là những gì mã tháo rời trông vào Reflector:Thay đổi tên thông số trong C# có thay đổi phá vỡ thời gian chạy không?

private static void Main() 
{ 
    bool CS$0$0000 = true; 
    Class1.DoSomething(CS$0$0000); 
    Console.ReadKey(); 
} 

... và đây là mã nguồn gốc:

static void Main() { 

    MyLib.Class1.DoSomething(a: true); 

    Console.ReadKey(); 
} 
+0

Có, bạn hiểu rõ điều này, nó không phải là vi phạm. Đến với một kịch bản mà nó đang phá vỡ là khó khăn, tôi không thể dễ dàng đưa ra một kịch bản ràng buộc muộn mà nó làm. –

Trả lời

19

Tôi đọc một vài bài báo nói rằng với việc giới thiệu các đối số được đặt tên trong C# 3.0, tên tham số hiện là một phần của hợp đồng công khai. Điều này có đúng không, và điều đó có nghĩa là gì?

Đúng là tên đối số là một phần của hợp đồng công khai, nhưng tuyên bố có hai lỗi.

Lỗi rõ ràng nhất là đối số được đặt tên đã được giới thiệu trong C# 4.0, không phải C# 3.0.

Nhưng lỗi phức tạp hơn là quan trọng hơn nhiều. Việc giới thiệu các đối số được đặt tên trong C# 4.0 không phải là bây giờ đặt tên cho các tham số một phần của hợp đồng công khai của một phương thức. Tên của tham số là luôn là một phần của hợp đồng công khai vì các ngôn ngữ khác với C# có tính năng đối số được đặt tên. Cụ thể, VB luôn hỗ trợ các đối số được đặt tên.

Do đó, thay đổi tên của tham số trong thư viện là luôn là thay đổi đột phá để biên dịch lại VB. Bây giờ nó cũng là một thay đổi phá vỡ cho C# biên dịch lại, nhưng điều đó không có nghĩa là nó đã được an toàn trước và bây giờ nó là nguy hiểm. Nó luôn nguy hiểm.

C# không phải là ngôn ngữ .NET duy nhất, không phải cho đến nay. Khi bạn thay đổi một phần bề mặt có thể nhìn thấy công khai của một loại, bạn có nguy cơ phá vỡ chương trình bằng mọi ngôn ngữ. C# có hoặc không có một tính năng không thay đổi thực tế đó.

11

Vấn đề là, nói rằng bạn có một API công cộng như vậy:

public void Foo(bool a = false) 
{ 
    //.... 

Người gọi có thể viết một ứng dụng sử dụng nó, như vậy:

Foo(a: true); 

Nếu bạn sau đó thay đổi phương pháp để:

public void Foo(bool aBetterName = false) 
{ 
    //.... 

Bây giờ, tất cả của một đột ngột, mã của người gọi sẽ không còn biên dịch, như trình biên dịch (ngay sau khi họ cập nhật vào thư viện mới của bạn) sẽ không còn thấy thông số có tên a.

+0

Phát hiện rõ nét và rõ ràng. Đá trên –

+1

Vâng, tôi hiểu đó là một sự thay đổi phá hoại. –

+0

@MaxToro: Điều đó có nghĩa là tất cả. Hợp đồng công khai là cố định, bởi vì bạn sẽ phá vỡ (tại thời gian biên dịch) người gọi khác. Nó không phải là một thay đổi phá vỡ thời gian chạy, mặc dù (như thêm một tham số sẽ là), vì sự thay thế tất cả được xử lý tại thời gian biên dịch. Lưu ý rằng việc thay đổi mặc định, tuy nhiên, sẽ không khiến người gọi khác cập nhật, vì tất cả được xử lý tại thời gian biên dịch. (Đối số tùy chọn/được đặt tên hoàn toàn là một thủ thuật biên dịch thời gian) –

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