BidirectionalDictionary<TFirst, TSecond>
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace Newtonsoft.Json.Utilities
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal class BidirectionalDictionary<TFirst, TSecond>
{
private readonly IDictionary<TFirst, TSecond> _firstToSecond;
private readonly IDictionary<TSecond, TFirst> _secondToFirst;
private readonly string _duplicateFirstErrorMessage;
private readonly string _duplicateSecondErrorMessage;
public BidirectionalDictionary()
: this((IEqualityComparer<TFirst>)EqualityComparer<TFirst>.Default, (IEqualityComparer<TSecond>)EqualityComparer<TSecond>.Default)
{
}
public BidirectionalDictionary(IEqualityComparer<TFirst> firstEqualityComparer, IEqualityComparer<TSecond> secondEqualityComparer)
: this(firstEqualityComparer, secondEqualityComparer, "Duplicate item already exists for '{0}'.", "Duplicate item already exists for '{0}'.")
{
}
public BidirectionalDictionary(IEqualityComparer<TFirst> firstEqualityComparer, IEqualityComparer<TSecond> secondEqualityComparer, string duplicateFirstErrorMessage, string duplicateSecondErrorMessage)
{
_firstToSecond = new Dictionary<TFirst, TSecond>(firstEqualityComparer);
_secondToFirst = new Dictionary<TSecond, TFirst>(secondEqualityComparer);
_duplicateFirstErrorMessage = duplicateFirstErrorMessage;
_duplicateSecondErrorMessage = duplicateSecondErrorMessage;
}
public void Set(TFirst first, TSecond second)
{
if (_firstToSecond.TryGetValue(first, out TSecond value) && !value.Equals(second))
throw new ArgumentException(_duplicateFirstErrorMessage.FormatWith(CultureInfo.InvariantCulture, first));
if (_secondToFirst.TryGetValue(second, out TFirst value2) && !value2.Equals(first))
throw new ArgumentException(_duplicateSecondErrorMessage.FormatWith(CultureInfo.InvariantCulture, second));
_firstToSecond.Add(first, second);
_secondToFirst.Add(second, first);
}
public bool TryGetByFirst(TFirst first, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TSecond second)
{
return _firstToSecond.TryGetValue(first, out second);
}
public bool TryGetBySecond(TSecond second, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TFirst first)
{
return _secondToFirst.TryGetValue(second, out first);
}
}
}