C# ngôn ngữ không phải là, nhưng .NET framework có thể.
Các Hợp đồng thư viện + các công cụ phân tích tĩnh được giới thiệu trong .NET 4 có thể giới thiệu sau đây:
Microsoft đang sử dụng [Immutable] và [tinh khiết] bên trong .NET 3.5 framework ngay bây giờ.
Ví dụ: xem [Microsoft.Contracts.Immutable] và [Microsoft.Contracts.Pure] bên trong .NET 3.5, trong System.Core.dll. Thật không may, họ đang nội bộ. Tuy nhiên, Microsoft.Contracts. * Chủ yếu được sinh ra từ nghiên cứu SpeC#, và SpeC# đã được xếp vào các API hợp đồng sẽ là một phần của .NET 4.0.
Chúng tôi sẽ xem điều gì xảy ra với điều này. Tôi đã không kiểm tra xem các bản phát hành .NET 4.0 bit trước có chứa bất kỳ API nào như [Pure] hay [Immutable] trong API hợp đồng hay không. Nếu họ làm, tôi tưởng tượng công cụ phân tích tĩnh sẽ là công cụ để thực thi quy tắc, chứ không phải là trình biên dịch.
chỉnh sửa Tôi vừa tải lên Microsoft.Contracts.dll từ latest pre-release drop of MS Code Contracts tuần này. Tin tốt: Các thuộc tính [Pure] và [Mutability (Mutability.Immutable)] tồn tại trong thư viện, cho thấy chúng sẽ nằm trong .NET 4.0. Woohoo!
chỉnh sửa 2 Bây giờ .NET 4 đã được phát hành, tôi đã tra cứu các loại này. [Pure] vẫn còn trong System.Diagnostics.Contracts không gian tên. Nó không nhằm mục đích sử dụng chung, mà là để sử dụng với kiểm tra trước và sau điều kiện của API hợp đồng. Nó không phải là trình biên dịch được thi hành, neither does the Code Contract checker tool enforce purity. [Mutability] đã biến mất. Điều thú vị là, nơi Microsoft đã sử dụng các thuộc tính Mutability và Pure trong .NET 3.5 (trong lớp BigInteger bên trong trong System.Core.dll), .NET 4 đã chuyển BigInteger sang System.Numerics và đã loại bỏ [Pure] và [Mutability] các thuộc tính ngoài loại đó. Dòng dưới cùng: nó xuất hiện .NET 4 không làm gì để xác minh tác dụng phụ.
chỉnh sửa 3 Với thời gian gần đây (cuối năm 2011) xem trước Microsoft Rosyln biên dịch-như-một-dịch vụ công cụ - được cho là lên kế hoạch cho RTM trong Visual Studio 2015 - trông giống như họ sẽ có thể hỗ trợ những thứ như thế này; bạn có thể viết các phần mở rộng cho trình biên dịch để kiểm tra độ tinh khiết và bất biến, và phát hành cảnh báo trình biên dịch nếu một thứ gì đó được trang trí với các thuộc tính đó không tuân theo các quy tắc. Mặc dù vậy, chúng tôi đang xem xét một vài năm để hỗ trợ điều này.
chỉnh sửa 4 Bây giờ Rosyln đang ở đây vào mùa hè năm 2015, khả năng xây dựng phần mở rộng trình biên dịch cho thuần khiết/bất biến thực sự tồn tại. Tuy nhiên, điều đó không làm bất cứ điều gì cho mã khung hiện có, cũng như mã thư viện của bên thứ ba. Nhưng trên đường chân trời là C# 7 proposal for immutable types. Điều này sẽ được thực thi bởi trình biên dịch và sẽ giới thiệu một từ khóa bất biến mới từ khóa thành C# và thuộc tính [Không thể thay đổi] trong khuôn khổ .NET. Cách sử dụng:
// Edit #4: This is a proposed design for C# 7 immutable as of June 2015.
// Compiler will implicitly mark all fields as readonly.
// Compiler will enforce all fields must be immutable types.
public immutable class Person
{
public Person(string firstName, string lastName, DateTimeOffset birthDay)
{
FirstName = firstName; // Properties can be assigned only in the constructor.
LastName = lastName;
BirthDay = birthDay;
}
public string FirstName { get; } // String is [Immutable], so OK to have as a readonly property
public string LastName { get; }
public DateTime BirthDay { get; } // Date is [Immutable] too.
}
chỉnh sửa 5 Đó là tháng 11 năm 2016, và nó xuất hiện loại không thay đổi được giảm từ C# 7. Luôn luôn có hy vọng cho C# 8. :-)
chỉnh sửa 6 Đó là tháng 11 năm 2017. C# 8 đang được xem đầy đủ, và trong khi chúng ta sẽ không có các hàm thuần túy, chúng ta sẽ có readonly structs. Điều này làm cho cấu trúc không thay đổi, cho phép tối ưu hóa một số trình biên dịch.
Một lưu ý khác, khi thả tuần trước, [Pure] là công khai, nhưng [Mutability (...)] là nội bộ. Chúng tôi sẽ xem liệu điều này có thay đổi không. –
Một điều cần lưu ý là liệu các thuộc tính này có nghĩa là để sử dụng chung hay không hoặc chúng chỉ được sử dụng trong các API hợp đồng. Tôi hy vọng họ thường hữu ích để được sử dụng trong một codebase, bất kể một là sử dụng các API System.Diagnostics.Contract thực tế. –
+1 để cập nhật câu trả lời cho câu hỏi cổ đại khi thế giới thay đổi. – Emile