特性
數據契約
簡介:
- 服務端和客戶端之間要傳送的自定義數據類型
- 當應用於類型的成員時,指定該成員是數據協定的一部分並可由 DataContractSerializer 進行序列化。
- 特性應用到的屬性必須同時具備 get 和 set 字段
- 由成員返回的數據(即便是私有的)會進行序列化和反序列化,所以惡意用戶或進程能夠查看或截獲這些數據。
例子
Types:
[DataContract]
public class File
{
// excluded from serialization
// does not have DataMemberAttribute
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int Size { get; set; }
}
Usage:
File file = new File
{
Id = Guid.NewGuid(),
Name = "ImportantLegalDocuments.docx",
Size = 50 * 1024
};
string json = JsonConvert.SerializeObject(file, Formatting.Indented);
Console.WriteLine(json);
// {
// "Name": "ImportantLegalDocuments.docx",
// "Size": 51200
// }
還能夠轉換爲字典類型
SortedDictionary<string, string> dicts = JsonConvert.DeserializeObject<SortedDictionary<string, string>>(JsonModel);
集合的選型
簡介
- 開發過程當中,咱們都知道java對於集合老是使用hashmap。我在日常開發過程當中通常都是list等,那麼關於集合咱們怎麼選擇呢?相似的數據在做爲集合而存儲和操做時一般能夠獲得更高效地處理。
命名空間
- system.Array
- System.Collections
- System.Collections.Generic
- System.Collections.Concurrent
- System.Collections.lmmutable
以上幾個集合的命名空間類主要做用這裏簡單介紹一下,與上面一一對應
- 用於建立、處理、搜索數組並對數組進行排序,從而充當公共語言運行時中全部數組的基類
- 接口和類定義各類對象(如列表、隊列、位數組、哈希表和字典)的集合。
- 定義泛型集合的接口和類,用戶可使用泛型集合來建立強類型集合,這種集合能提供比非泛型強類型集合更好的類型安全性和性能。
- 提供多個線程安全集合類。當有多個線程併發訪問集合時,應使用這些類代替 System.Collections 和 System.Collections.Generic 命名空間中的對應類型。 可是,不保證經過擴展方法或經過顯式接口實現訪問集合對象是線程安全的,可能須要由調用方進行同步
- 包含用於定義不可變集合的接口和類。
經常使用集合功能
實現集合的操做。能夠直接或間接實現 ICollection 接口或 ICollection
接口,這些接口的集合均共享這些功能:
java
- 可枚舉集合
將枚舉器看做集合中可指向任何元素的可移動指針,可使用
- 可將集合內容複製到數組
獲得的數組始終是一維的,下限爲零
- 容量和計數屬性
當達到當前容量時,大多數的集合都會自動擴展容量。具體操做:從新分配內存並將元素從舊的集合複製都新的集合,這減小了要求使用集合的代碼;性能可能會收到不利影響。例如,對 List
來講,若是 Count 比 Capacity 少,那麼添加項就是一項 O(1) 操做。 如需增長容量以容納新元素,則添加項成爲 O(n) 操做,其中 n 是 Count。 避免因屢次從新分配而致使的性能較差的最佳方式是:將初始容量設置爲集合的估計大小。
BitArray 是一種特殊狀況;它的容量與其長度相同,而其長度與其計數相同。
- 下限一致
- 同步以從多個線程進行訪問(僅 System.Collections 類)
集合複雜度
可變 |
複雜度最優 |
複雜度最壞 |
不可變 |
複雜度 |
Stack
.Push
|
O(1) |
O(n) |
ImmutableStack
.Push
|
O(1) |
Queue
.Enqueue
|
O(1) |
O(n) |
ImmutableQueue
.Enqueue
|
O(1) |
List
.Add
|
O(1) |
O(n) |
ImmutableList
.Add
|
O(log n) |
List
.Item[Int32]
|
O(1) |
O(1) |
ImmutableList
.Item[Int32]
|
O(log n) |
List
.Enumerator
|
O(n) |
O(n) |
ImmutableList
.Enumerator
|
O(n) |
HashSet
.Add, lookup
|
O(1) |
O(n) |
ImmutableHashSet
.Add
|
O(log n) |
SortedSet
.Add
|
O(log n) |
O(n) |
ImmutableSortedSet
.Add
|
O(log n) |
Dictionary
.Add
|
O(1) |
O(n) |
ImmutableDictionary
.Add
|
O(log n) |
Dictionary
lookup
|
O(1) |
O(1) -或者從嚴格意義上說,O(n) |
ImmutableDictionary
lookup
|
O(log n) |
SortedDictionary
.Add
|
O(log n) |
O(n log n) |
ImmutableSortedDictionary
.Add
|
O(log n) |
ImmutableList
在 for 循環內的效果較差。 使用 foreach 循環枚舉 ImmutableList
頗有效,由於 ImmutableList
使用二進制樹來存儲其數據,而不是像 List
那樣使用簡單數組。 數組能夠很是快速地編入索引,但必須向下遍歷二進制樹,直到找到具備所需索引的節點。
此外,SortedSet
與 ImmutableSortedSet
的複雜性相同。 這是由於它們都使用了二進制樹。 固然,顯著的差別在於 ImmutableSortedSet
使用不可變的二進制樹。 因爲 ImmutableSortedSet
還提供了一個容許變化的 System.Collections.Immutable.ImmutableSortedSet
.Builder 類,所以能夠同時實現不可變性和保障性能。
json
如何選擇集合
順序列表(檢索元素值後就將該元素丟棄)
- FIFO :Queue/ Queue
/
- LIFO :Stack 類或 Stack
泛型類
- 多個線程進行安全訪問,ConcurrentQueue
/ConcurrentStack
。
- 不可變性, ImmutableQueue
和 ImmutableStack
。
- LinkedList
泛型類容許從開頭到末尾或從末尾到開頭的順序訪問
按索引訪問每一個元素
- ArrayList 和 StringCollection 類以及 List
泛型類按從零開始的元素索引提供對其元素的訪問。 若是要得到不可變性,請考慮不可變泛型版本 ImmutableArray
和 ImmutableList
。
- Hashtable、SortedList、ListDictionary 和 StringDictionary 類以及 Dictionary<TKey,TValue> 和 SortedDictionary<TKey,TValue> 泛型類按元素的鍵提供對其元素的訪問。 此外,還有幾個相應類型的不可變版本:ImmutableHashSet
、ImmutableDictionary<TKey,TValue>、ImmutableSortedSet
和 ImmutableSortedDictionary<TKey,TValue>。
- NameObjectCollectionBase 和 NameValueCollection 類以及 KeyedCollection<TKey,TItem> 和 SortedList<TKey,TValue> 泛型類按從零開始的元素索引或元素的鍵提供對其元素的訪問。
每一個元素都包含一個值、一個鍵和一個值的組合或一個鍵和多個值的組合
- 一個值:使用任何基於 IList 接口或 IList
泛型接口的集合。 要得到不可變選項,請考慮 IImmutableList
泛型接口。
- 鍵值對:使用任何基於 IDictionary 接口或 IDictionary<TKey,TValue> 泛型接口的集合。 要得到不可變選項,請考慮 IImmutableSet
或 IImmutableDictionary<TKey,TValue> 泛型接口。
- 帶有嵌入鍵的值:使用 KeyedCollection<TKey,TItem> 泛型類。
- 一個鍵和多個值:使用 NameValueCollection 類。
須要快速搜索和信息檢索
- 對於小集合(10 項或更少),ListDictionary 速度比 Hashtable 快。 Dictionary<TKey,TValue> 泛型類提供比 SortedDictionary<TKey,TValue> 泛型類更快的查找。 多線程的實現爲 ConcurrentDictionary<TKey,TValue>。 ConcurrentBag
爲無序數據提供快速的多線程插入。
只接受字符串的集合
- StringCollection(基於 IList)和 StringDictionary(基於 IDictionary)位於 System.Collections.Specialized 命名空間。
- 此外,經過指定其泛型類參數的 String 類,可使用 System.Collections.Generic 命名空間中的任何泛型集合類做爲強類型字符串集合。 例如,能夠將變量聲明爲採用 List
或 Dictionary<String,String> 類型。
以與輸入方式不一樣的方式對元素進行排序
- Hashtable 類按其哈希代碼對其元素進行排序。
- SortedList 類以及 SortedList<TKey,TValue> 和 SortedDictionary<TKey,TValue> 泛型類按鍵對元素進行排序。 排序順序的依據爲,實現 SortedList 類的 IComparer 接口和實現 SortedList<TKey,TValue> 和SortedDictionary<TKey,TValue> 泛型類的 IComparer
泛型接口。 在這兩種泛型類型中,雖然 SortedDictionary<TKey,TValue> 的性能優於 SortedList<TKey,TValue>,但 SortedList<TKey,TValue> 佔用的內存更少。
- ArrayList 提供了一種 Sort 方法,此方法採用 IComparer 實現做爲參數。 其泛型對應項(List
泛型類)提供一種 Sort 方法,此方法採用 IComparer
泛型接口的實現做爲參數。
泛型集合爲什麼比非泛型好
- 泛型時沒必要對元素進行裝箱
- 可得到類型安全的自動化優勢而無需從基集合類型派生和實現特定類型的成員
集合內的比較和排序
檢查相等
泛型:數組
- 若是類型 T 實現 IEquatable
泛型接口,則相等比較器是該接口的 Equals 方法。
- 若是類型 T 未實現 IEquatable
,則使用 Object.Equals 。
此外,字典集合的某些構造函數重載接受 IEqualityComparer
實現,用於比較鍵是否相等。
排序
- 若是類型 T 實現 System.IComparable<T> 泛型接口,則默認比較器是該接口的 IComparable<T>.CompareTo(T) 方法。
- 若是類型 T 實現非泛型 System.IComparable 接口,則默認比較器是該接口的 IComparable.CompareTo(Object) 方法。
- 若是類型 T 未實現任何接口,則沒有默認比較器,必須顯式提供一個比較器或比較委託。
爲了提供顯式比較,某些方法接受 IComparer 實現做爲參數。 例如, List
.Sort 方法接受 System.Collections.Generic.IComparer
實現。
參考https://docs.microsoft.com/zh-cn/dotnet/standard/collections/hashtable-and-dictionary-collection-types
總結:通常處理幾百幾千數據除特殊要求外。List都夠用,具體能夠參考個人多線程和代碼優化部分
安全