📄 readonlymultidictionarybase.cs
字号:
builder.Append("}");
return builder.ToString();
}
/// <summary>
/// Display the contents of the dictionary in the debugger. This is intentionally private, it is called
/// only from the debugger due to the presence of the DebuggerDisplay attribute. It is similar
/// format to ToString(), but is limited to 250-300 characters or so, so as not to overload the debugger.
/// </summary>
/// <returns>The string representation of the items in the collection, similar in format to ToString().</returns>
new internal string DebuggerDisplayString()
{
const int MAXLENGTH = 250;
bool firstItem = true;
System.Text.StringBuilder builder = new System.Text.StringBuilder();
builder.Append("{");
// Call ToString on each item and put it in.
foreach (KeyValuePair<TKey, ICollection<TValue>> pair in this) {
if (builder.Length >= MAXLENGTH) {
builder.Append(", ...");
break;
}
if (!firstItem)
builder.Append(", ");
if (pair.Key == null)
builder.Append("null");
else
builder.Append(pair.Key.ToString());
builder.Append("->");
// Put all values in a parenthesized list.
builder.Append('(');
bool firstValue = true;
foreach (TValue val in pair.Value) {
if (!firstValue)
builder.Append(",");
if (val == null)
builder.Append("null");
else
builder.Append(val.ToString());
firstValue = false;
}
builder.Append(')');
firstItem = false;
}
builder.Append("}");
return builder.ToString();
}
/// <summary>
/// Enumerate all the keys in the dictionary, and for each key, the collection of values for that key.
/// </summary>
/// <returns>An enumerator to enumerate all the key, ICollection<value> pairs in the dictionary.</returns>
public override IEnumerator<KeyValuePair<TKey, ICollection<TValue>>> GetEnumerator()
{
using (IEnumerator<TKey> enumKeys = EnumerateKeys()) {
while (enumKeys.MoveNext()) {
TKey key = enumKeys.Current;
yield return new KeyValuePair<TKey, ICollection<TValue>>(key, new ValuesForKeyCollection(this, key));
}
}
}
#region Keys and Values collections
/// <summary>
/// A private class that provides the ICollection<TValue> for a particular key. This is the collection
/// that is returned from the indexer. The collections is read-write, live, and can be used to add, remove,
/// etc. values from the multi-dictionary.
/// </summary>
[Serializable]
private sealed class ValuesForKeyCollection : ReadOnlyCollectionBase<TValue>
{
private ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary;
private TKey key;
/// <summary>
/// Constructor. Initializes this collection.
/// </summary>
/// <param name="myDictionary">Dictionary we're using.</param>
/// <param name="key">The key we're looking at.</param>
public ValuesForKeyCollection(ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary, TKey key)
{
this.myDictionary = myDictionary;
this.key = key;
}
/// <summary>
/// Get the number of values associated with the key.
/// </summary>
public override int Count
{
get
{
return myDictionary.CountValues(key);
}
}
/// <summary>
/// A simple function that returns an IEnumerator<TValue> that
/// doesn't yield any values. A helper.
/// </summary>
/// <returns>An IEnumerator<TValue> that yields no values.</returns>
private IEnumerator<TValue> NoValues()
{
yield break;
}
/// <summary>
/// Enumerate all the values associated with key.
/// </summary>
/// <returns>An IEnumerator<TValue> that enumerates all the values associated with key.</returns>
public override IEnumerator<TValue> GetEnumerator()
{
IEnumerator<TValue> values;
if (myDictionary.TryEnumerateValuesForKey(key, out values))
return values;
else
return NoValues();
}
/// <summary>
/// Determines if the given values is associated with key.
/// </summary>
/// <param name="item">Value to check for.</param>
/// <returns>True if value is associated with key, false otherwise.</returns>
public override bool Contains(TValue item)
{
return myDictionary.Contains(key, item);
}
}
/// <summary>
/// A private class that implements ICollection<TKey> and ICollection for the
/// Keys collection. The collection is read-only.
/// </summary>
[Serializable]
private sealed class KeysCollection : ReadOnlyCollectionBase<TKey>
{
private ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="myDictionary">The dictionary this is associated with.</param>
public KeysCollection(ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary)
{
this.myDictionary = myDictionary;
}
public override int Count
{
get { return myDictionary.Count; }
}
public override IEnumerator<TKey> GetEnumerator()
{
return myDictionary.EnumerateKeys();
}
public override bool Contains(TKey key)
{
return myDictionary.ContainsKey(key);
}
}
/// <summary>
/// A private class that implements ICollection<TValue> and ICollection for the
/// Values collection. The collection is read-only.
/// </summary>
[Serializable]
private sealed class ValuesCollection : ReadOnlyCollectionBase<TValue>
{
private ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary;
public ValuesCollection(ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary)
{
this.myDictionary = myDictionary;
}
public override int Count
{
get { return myDictionary.CountAllValues(); }
}
public override IEnumerator<TValue> GetEnumerator()
{
using (IEnumerator<TKey> enumKeys = myDictionary.EnumerateKeys()) {
while (enumKeys.MoveNext()) {
TKey key = enumKeys.Current;
IEnumerator<TValue> enumValues;
if (myDictionary.TryEnumerateValuesForKey(key, out enumValues)) {
using (enumValues) {
while (enumValues.MoveNext())
yield return enumValues.Current;
}
}
}
}
}
public override bool Contains(TValue value)
{
foreach (TValue v in this) {
if (myDictionary.EqualValues(v, value))
return true;
}
return false;
}
}
/// <summary>
/// A private class that implements ICollection<IEnumerable<TValue>> and ICollection for the
/// Values collection on IDictionary. The collection is read-only.
/// </summary>
[Serializable]
private sealed class EnumerableValuesCollection : ReadOnlyCollectionBase<ICollection<TValue>>
{
private ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary;
public EnumerableValuesCollection(ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary)
{
this.myDictionary = myDictionary;
}
public override int Count
{
get { return myDictionary.Count; }
}
public override IEnumerator<ICollection<TValue>> GetEnumerator()
{
using (IEnumerator<TKey> enumKeys = myDictionary.EnumerateKeys()) {
while (enumKeys.MoveNext()) {
TKey key = enumKeys.Current;
yield return new ValuesForKeyCollection(myDictionary, key);
}
}
}
public override bool Contains(ICollection<TValue> values)
{
if (values == null)
return false;
TValue[] valueArray = Algorithms.ToArray(values);
foreach (ICollection<TValue> v in this) {
if (v.Count != valueArray.Length)
continue;
// First check in order for efficiency.
if (Algorithms.EqualCollections(v, values, myDictionary.EqualValues))
return true;
// Now check not in order. We can't use Algorithms.EqualSets, because we don't
// have an IEqualityComparer, just the ability to compare for equality. Unfortunately this is N squared,
// but there isn't a good choice here. We don't really expect this method to be used much.
bool[] found = new bool[valueArray.Length];
foreach (TValue x in v) {
for (int i = 0; i < valueArray.Length; ++i) {
if (!found[i] && myDictionary.EqualValues(x, valueArray[i]))
found[i] = true;
}
}
if (Array.IndexOf(found, false) < 0)
return true; // every item was found. The sets must be equal.
}
return false;
}
}
/// <summary>
/// A private class that implements ICollection<KeyValuePair<TKey,TValue>> and ICollection for the
/// KeyValuePairs collection. The collection is read-only.
/// </summary>
[Serializable]
private sealed class KeyValuePairsCollection : ReadOnlyCollectionBase<KeyValuePair<TKey, TValue>>
{
private ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary;
public KeyValuePairsCollection(ReadOnlyMultiDictionaryBase<TKey, TValue> myDictionary)
{
this.myDictionary = myDictionary;
}
public override int Count
{
get { return myDictionary.CountAllValues(); }
}
public override IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
using (IEnumerator<TKey> enumKeys = myDictionary.EnumerateKeys()) {
while (enumKeys.MoveNext()) {
TKey key = enumKeys.Current;
IEnumerator<TValue> enumValues;
if (myDictionary.TryEnumerateValuesForKey(key, out enumValues)) {
using (enumValues) {
while (enumValues.MoveNext())
yield return new KeyValuePair<TKey, TValue>(key, enumValues.Current);
}
}
}
}
}
public override bool Contains(KeyValuePair<TKey, TValue> pair)
{
return myDictionary[pair.Key].Contains(pair.Value);
}
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -