Skip to content
This repository was archived by the owner on Dec 20, 2022. It is now read-only.

Commit c3ac9d8

Browse files
committed
feat: 增加 IReadOnlyNamedCollection 接口,并调整相关代码的实现。 ®️
1 parent 63e3496 commit c3ac9d8

File tree

6 files changed

+335
-159
lines changed

6 files changed

+335
-159
lines changed

src/Collections/INamedCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace Zongsoft.Collections
3232
/// <summary>
3333
/// 表示命名集合基类的接口。
3434
/// </summary>
35-
/// <typeparam name="T"></typeparam>
35+
/// <typeparam name="T">集合成员的类型。</typeparam>
3636
public interface INamedCollection<T> : ICollection<T>
3737
{
3838
/// <summary>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Authors:
3+
* 钟峰(Popeye Zhong) <zongsoft@gmail.com>
4+
*
5+
* Copyright (C) 2013-2017 Zongsoft Corporation <http://www.zongsoft.com>
6+
*
7+
* This file is part of Zongsoft.CoreLibrary.
8+
*
9+
* Zongsoft.CoreLibrary is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 2.1 of the License, or (at your option) any later version.
13+
*
14+
* Zongsoft.CoreLibrary is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* The above copyright notice and this permission notice shall be
20+
* included in all copies or substantial portions of the Software.
21+
*
22+
* You should have received a copy of the GNU Lesser General Public
23+
* License along with Zongsoft.CoreLibrary; if not, write to the Free Software
24+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25+
*/
26+
27+
using System;
28+
using System.Collections.Generic;
29+
30+
namespace Zongsoft.Collections
31+
{
32+
/// <summary>
33+
/// 表示命名集合基类的接口。
34+
/// </summary>
35+
/// <typeparam name="T">集合成员的类型。</typeparam>
36+
public interface IReadOnlyNamedCollection<T> : IReadOnlyCollection<T>
37+
{
38+
/// <summary>
39+
/// 判断当前集合是否包含指定名称的元素。
40+
/// </summary>
41+
/// <param name="name">指定要判断的元素名。</param>
42+
/// <returns>如果指定名称的元素是存在的则返回真(True),否则返回假(False)。</returns>
43+
bool Contains(string name);
44+
45+
/// <summary>
46+
/// 获取指定名称的元素。
47+
/// </summary>
48+
/// <param name="name">指定要获取的元素名。</param>
49+
/// <returns>返回指定名称的元素对象,如果没有找到则抛出<seealso cref="KeyNotFoundException"/>异常。</returns>
50+
/// <exception cref="KeyNotFoundException">当指定<paramref name="name"/>名称的元素不存在则激发该异常。</exception>
51+
T Get(string name);
52+
53+
/// <summary>
54+
/// 尝试获取指定名称的元素。
55+
/// </summary>
56+
/// <param name="name">指定要获取的元素名。</param>
57+
/// <param name="value">输出参数,包含指定名称的元素对象。</param>
58+
/// <returns>返回一个值,指示指定名称的元素是否获取成功。</returns>
59+
bool TryGet(string name, out T value);
60+
}
61+
}

src/Collections/NamedCollectionBase.cs

Lines changed: 11 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,20 @@
3030

3131
namespace Zongsoft.Collections
3232
{
33-
public abstract class NamedCollectionBase<T> : ICollection<T>, ICollection, INamedCollection<T>
33+
public abstract class NamedCollectionBase<T> : ReadOnlyNamedCollectionBase<T>, ICollection<T>, INamedCollection<T>
3434
{
35-
#region 成员字段
36-
private readonly Dictionary<string, T> _innerDictionary;
37-
#endregion
38-
3935
#region 构造函数
40-
public NamedCollectionBase()
36+
protected NamedCollectionBase()
4137
{
42-
_innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
4338
}
4439

45-
public NamedCollectionBase(StringComparer comparer)
40+
protected NamedCollectionBase(StringComparer comparer) : base(comparer)
4641
{
47-
_innerDictionary = new Dictionary<string, T>(comparer ?? StringComparer.OrdinalIgnoreCase);
4842
}
4943
#endregion
5044

5145
#region 公共属性
52-
public T this[string name]
46+
public new T this[string name]
5347
{
5448
get
5549
{
@@ -60,40 +54,6 @@ public T this[string name]
6054
this.SetItem(name, value);
6155
}
6256
}
63-
64-
public int Count
65-
{
66-
get
67-
{
68-
return _innerDictionary.Count;
69-
}
70-
}
71-
72-
public IEnumerable<string> Keys
73-
{
74-
get
75-
{
76-
return _innerDictionary.Keys;
77-
}
78-
}
79-
80-
public IEnumerable<T> Values
81-
{
82-
get
83-
{
84-
return _innerDictionary.Values;
85-
}
86-
}
87-
#endregion
88-
89-
#region 保护方法
90-
protected IDictionary<string, T> InnerDictionary
91-
{
92-
get
93-
{
94-
return _innerDictionary;
95-
}
96-
}
9757
#endregion
9858

9959
#region 公共方法
@@ -102,38 +62,6 @@ public void Clear()
10262
this.ClearItems();
10363
}
10464

105-
public bool Contains(string name)
106-
{
107-
return this.ContainsName(name);
108-
}
109-
110-
public void CopyTo(T[] array, int arrayIndex)
111-
{
112-
if(array == null)
113-
throw new ArgumentNullException(nameof(array));
114-
115-
if(arrayIndex < 0 || arrayIndex >= array.Length)
116-
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
117-
118-
var iterator = _innerDictionary.GetEnumerator();
119-
120-
for(int i = arrayIndex; i < array.Length; i++)
121-
{
122-
if(iterator.MoveNext())
123-
array[i] = iterator.Current.Value;
124-
}
125-
}
126-
127-
public T Get(string name)
128-
{
129-
return this.GetItem(name);
130-
}
131-
132-
public bool TryGet(string name, out T value)
133-
{
134-
return this.TryGetItem(name, out value);
135-
}
136-
13765
public void Add(T item)
13866
{
13967
this.AddItem(item);
@@ -148,55 +76,31 @@ public bool Remove(string name)
14876
#region 虚拟方法
14977
protected virtual void ClearItems()
15078
{
151-
_innerDictionary.Clear();
152-
}
153-
154-
protected virtual bool ContainsName(string name)
155-
{
156-
return _innerDictionary.ContainsKey(name);
157-
}
158-
159-
protected virtual T GetItem(string name)
160-
{
161-
T value;
162-
163-
if(_innerDictionary.TryGetValue(name, out value))
164-
return value;
165-
166-
throw new KeyNotFoundException();
79+
this.InnerDictionary.Clear();
16780
}
16881

16982
protected virtual void SetItem(string name, T value)
17083
{
17184
var key = this.GetKeyForItem(value);
172-
var comparer = (StringComparer)_innerDictionary.Comparer;
85+
var comparer = (StringComparer)this.InnerDictionary.Comparer;
17386

17487
if(comparer.Compare(key, name) != 0)
17588
throw new InvalidOperationException("Specified name not equal to computed key of the item.");
17689

177-
_innerDictionary[name] = value;
178-
}
179-
180-
protected virtual bool TryGetItem(string name, out T value)
181-
{
182-
return _innerDictionary.TryGetValue(name, out value);
90+
this.InnerDictionary[name] = value;
18391
}
18492

18593
protected virtual void AddItem(T item)
18694
{
187-
_innerDictionary.Add(this.GetKeyForItem(item), item);
95+
this.InnerDictionary.Add(this.GetKeyForItem(item), item);
18896
}
18997

19098
protected virtual bool RemoveItem(string name)
19199
{
192-
return _innerDictionary.Remove(name);
100+
return this.InnerDictionary.Remove(name);
193101
}
194102
#endregion
195103

196-
#region 抽象方法
197-
protected abstract string GetKeyForItem(T item);
198-
#endregion
199-
200104
#region 显式实现
201105
bool ICollection<T>.IsReadOnly
202106
{
@@ -206,65 +110,14 @@ bool ICollection<T>.IsReadOnly
206110
}
207111
}
208112

209-
bool ICollection.IsSynchronized
210-
{
211-
get
212-
{
213-
return ((ICollection)_innerDictionary).IsSynchronized;
214-
}
215-
}
216-
217-
object ICollection.SyncRoot
218-
{
219-
get
220-
{
221-
return ((ICollection)_innerDictionary).SyncRoot;
222-
}
223-
}
224-
225-
void ICollection.CopyTo(Array array, int arrayIndex)
226-
{
227-
if(array == null)
228-
throw new ArgumentNullException(nameof(array));
229-
230-
if(arrayIndex < 0 || arrayIndex >= array.Length)
231-
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
232-
233-
var iterator = _innerDictionary.GetEnumerator();
234-
235-
for(int i = arrayIndex; i < array.Length; i++)
236-
{
237-
if(iterator.MoveNext())
238-
array.SetValue(iterator.Current.Value, i);
239-
}
240-
}
241-
242113
bool ICollection<T>.Contains(T item)
243114
{
244-
return _innerDictionary.ContainsKey(this.GetKeyForItem(item));
115+
return this.InnerDictionary.ContainsKey(this.GetKeyForItem(item));
245116
}
246117

247118
bool ICollection<T>.Remove(T item)
248119
{
249-
return _innerDictionary.Remove(this.GetKeyForItem(item));
250-
}
251-
#endregion
252-
253-
#region 遍历枚举
254-
IEnumerator IEnumerable.GetEnumerator()
255-
{
256-
foreach(var entry in _innerDictionary)
257-
{
258-
yield return entry.Value;
259-
}
260-
}
261-
262-
public IEnumerator<T> GetEnumerator()
263-
{
264-
foreach(var entry in _innerDictionary)
265-
{
266-
yield return entry.Value;
267-
}
120+
return this.InnerDictionary.Remove(this.GetKeyForItem(item));
268121
}
269122
#endregion
270123
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Authors:
3+
* 钟峰(Popeye Zhong) <zongsoft@gmail.com>
4+
*
5+
* Copyright (C) 2013-2018 Zongsoft Corporation <http://www.zongsoft.com>
6+
*
7+
* This file is part of Zongsoft.CoreLibrary.
8+
*
9+
* Zongsoft.CoreLibrary is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 2.1 of the License, or (at your option) any later version.
13+
*
14+
* Zongsoft.CoreLibrary is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* The above copyright notice and this permission notice shall be
20+
* included in all copies or substantial portions of the Software.
21+
*
22+
* You should have received a copy of the GNU Lesser General Public
23+
* License along with Zongsoft.CoreLibrary; if not, write to the Free Software
24+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25+
*/
26+
27+
using System;
28+
29+
namespace Zongsoft.Collections
30+
{
31+
public class ReadOnlyNamedCollection<T> : ReadOnlyNamedCollectionBase<T>
32+
{
33+
#region 成员字段
34+
private Func<T, string> _getKey;
35+
#endregion
36+
37+
#region 构造函数
38+
public ReadOnlyNamedCollection(Func<T, string> getKey, StringComparer comparer = null) : base(comparer)
39+
{
40+
_getKey = getKey ?? throw new ArgumentNullException(nameof(getKey));
41+
}
42+
#endregion
43+
44+
#region 重写方法
45+
protected override string GetKeyForItem(T item)
46+
{
47+
return _getKey(item);
48+
}
49+
#endregion
50+
}
51+
}

0 commit comments

Comments
 (0)