Các lựa chọn thay thế bất biến cho một mảng mã sản xuất trong C# (ít nhất là trong khi ImmutableArray là bản beta)?Lựa chọn thay thế bất biến cho một mảng trong C# là gì?
Trả lời
Bạn nên cung cấp thêm chi tiết, nhưng một tùy chọn là System.Collections.ObjectModel.ReadOnlyCollection<>
hoạt động như một danh sách/mảng. Nó có thể được tạo ra như thế này:
var immutable1 = Array.AsReadOnly(new[] { 7, 9, 13, });
var immutable2 = (new List<int> { 7, 9, 13, }).AsReadOnly();
Nó là một gói bao quanh một IList<>
. Nó không thể được truyền tới bất cứ thứ gì cho phép thay đổi danh sách/mảng bên dưới. Nhưng đối tượng cơ bản có thể đạt được với sự phản chiếu, tất nhiên.
Nếu ai đó ở nơi khác thay đổi danh sách/mảng "bên trong", sẽ được tinh chỉnh trong trình bao bọc ReadOnlyCollection<>
. Không có bản sao nào được thực hiện.
Đây là hình thức bất biến "nông". Nếu các mục riêng lẻ có thể thay đổi (không thể int
), trình bao bọc sẽ không cấm điều đó.
Một điều rẻ hơn để làm là chỉ cần sử dụng giao diện IReadOnlyList<out T>
đó là hiệp biến trong T
(thêm một lợi thế). Cả hai List<T>
và T[]
triển khai giao diện này. Vì vậy:
IReadOnlyList<int> immutable3 = new[] { 7, 9, 13, };
IReadOnlyList<int> immutable4 = new List<int> { 7, 9, 13, };
Trong trường hợp đó, tuy nhiên, người tiêu dùng có thể kiểm tra immutable3 as IList<int>
, ví dụ, hoặc immutable3 as int[]
, và có được một "có thể thay đổi kiểu tài liệu tham khảo" cho các đối tượng có thể thay đổi (không phản ánh).
Tuy nhiên, có loại không thay đổi (ví dụ như ImmutableList<>
) mà không phải là "trong phiên bản beta" trong Microsoft.Immutable.Collections. Vì vậy, bạn có thể xem xét cài đặt đó nếu bạn thực sự cần nó. Nó không phải là một phần của thư viện .NET chuẩn, vì vậy bạn sẽ phải cài đặt nó một cách riêng biệt.
Để giải thích ý tôi bằng cách "cạn", giả sử bạn có một mảng có loại phần tử trong chính nó có thể thay đổi. Sau đó, không có vấn đề mà các đề xuất ở trên bạn sử dụng, mọi người vẫn có thể modyfy các mục. Ví dụ:
StringBuilder[] yourArray = {
new StringBuilder("All"),
new StringBuilder("is"),
new StringBuilder("good"),
};
var immutable = ImmutableList<StringBuilder>.Empty.AddRange(yourArray);
immutable[0].Insert(0, "NOT ");
immutable[1].Clear();
immutable[2].Append(new string('!', 10000));
Ngoài ra, lưu ý rằng bộ sưu tập chỉ đọc không phải là bản sao. Vì vậy, bạn phải chắc chắn rằng danh sách/mảng cơ bản không bị rò rỉ, bởi vì điều đó sẽ làm thay đổi trình bao bọc chỉ đọc. – Luaan
@Luaan Điểm tốt. Tôi đã đề cập đến nó trong câu trả lời của tôi ngay bây giờ. –
Bộ sưu tập không thể thay đổi Gói NuGet * vẫn * beta (hoặc ít nhất là trạng thái RC): "System.Collections.Immutable 1.1.34 ** - rc **" – Brandon
Những bất lợi đến chỉ sử dụng ReadOnlyCollection
hoặc IReadOnlyList
là những cung cấp đảm bảo yếu hơn nhiều so với một mảng bất biến. Các đối tượng này chỉ đảm bảo rằng người giữ bộ sưu tập chỉ đọc sẽ không sửa đổi nó. Họ không đảm bảo rằng bộ sưu tập sẽ không được sửa đổi bởi mã giữ một tham chiếu đến bộ sưu tập cơ bản.
Cụ thể, người tiêu dùng đối tượng như vậy vẫn phải sử dụng đồng bộ hóa trong khi đọc từ bộ sưu tập, vì không đảm bảo rằng chủ sở hữu của bộ sưu tập cơ bản không bận thêm/xóa mục khỏi bộ sưu tập khi bạn đọc nó qua lense chỉ đọc của bạn. Hoặc bạn phải có một thỏa thuận được tài liệu giữa người tiêu dùng và nhà sản xuất rằng bộ sưu tập sẽ không bị sửa đổi.
Nếu bạn thực sự muốn một mảng bất biến và bạn không thể sử dụng gói Bộ sưu tập không thể thay đổi vì lý do nào đó, thì hãy đảm bảo nguồn không bao giờ sửa đổi mảng, mà thay vào đó nhân bản nó bất cứ khi nào muốn thay đổi. Kết hợp điều này với việc đưa ra các xử lý "chỉ đọc" để thực hiện các mảng không thể thay đổi.
LINQ làm cho nó khá dễ dàng để thực hiện của riêng bạn, mặc dù nó không phải là terribly thông minh. Ví dụ về việc xóa một mục trong một mảng với một mục khác theo cách không thay đổi:
private int[] _array;
public void RemoveItem(int item)
{
_array = _array.Where(x => x != item).ToArray();
}
/// <summary>Gets immutable array</summary>
public IReadOnlyList<int> Data { get { return _array; } }
Ok, cảm ơn thông tin :) Tôi đoán ImmutableList sẽ là lựa chọn tốt nhất hiện nay. – karl25233
Một cách để đối phó với mối quan tâm đó là sao chép toàn bộ danh sách/mảng và sau đó bọc _copy_ trong một 'ReadOnlyCollection <>' (hoặc upcast bản sao vào 'IReadOnlyList <> '). Nếu bạn viết nó như 'var safe = originalArray.ToList(). AsReadOnly();' bạn có thể chắc chắn rằng không ai có một tham chiếu đến trung gian 'List <>' được tạo ra (vì bạn không giữ tham chiếu đó). –
- 1. Một số lựa chọn thay thế cho PlayN là gì?
- 2. Các lựa chọn thay thế cho nút radio là gì?
- 3. Một số lựa chọn thay thế pagerank là gì?
- 4. Lựa chọn thay thế cho mẫu C++?
- 5. Các lựa chọn thay thế cho thư viện đa dữ liệu cho C/C++ là gì?
- 6. Các lựa chọn thay thế cho DataGridView là gì?
- 7. Lựa chọn thay thế EasyHook cho C#
- 8. Lựa chọn thay thế SQLite cho C++
- 9. Một số lựa chọn thay thế cho một Workflow Engine là gì?
- 10. Một số lựa chọn thay thế nhẹ cho django-sentry để đăng nhập là gì?
- 11. Lựa chọn thay thế thành viên ASP.NET là gì
- 12. Lựa chọn thay thế cho Inflector.Net
- 13. Lựa chọn thay thế cho underscore.js
- 14. Lựa chọn thay thế cho ppl
- 15. Lựa chọn thay thế cho Điều kiện
- 16. Với Silverlight biến mất khỏi Chrome 45, lựa chọn thay thế của tôi là gì?
- 17. Lựa chọn thay thế cho readmemh trong Verilog
- 18. Lựa chọn thay thế cho TOAD (Linux)
- 19. Các lựa chọn thay thế cho Trình quản lý Phiên bản Ruby (rvm) là gì?
- 20. Lựa chọn thay thế cho gettext?
- 21. Lựa chọn thay thế cho HtmlAgilityPack?
- 22. Lựa chọn thay thế cho popen/pclose?
- 23. Lựa chọn thay thế cho MySQL
- 24. Lựa chọn thay thế cho ArcGIS Server
- 25. Lựa chọn thay thế cho YQL
- 26. Các lựa chọn thay thế cho đa hình phụ trong scala là gì?
- 27. Lựa chọn thay thế cho JUnit
- 28. Các lựa chọn thay thế Vim phổ biến?
- 29. Lựa chọn thay thế nhẹ cho NHibernate
- 30. Lựa chọn thay thế cho iframe srcdoc?
Mục tiêu bạn đang cố đạt được là gì? Có lẽ đi qua một 'IEnumerable' thay vì một mảng có thể giải quyết vấn đề của bạn? –
Tôi đoán mảng nhanh chóng nhận được số lượng và đọc tất cả nội dung trong một lần (trong trường hợp cụ thể của chúng, chúng sẽ nằm trong bộ nhớ và được truy cập bởi một số chủ đề, thường chứa 10-1000 mục) – karl25233