Proper implementation of a bidirectional dictionary, also known as "BiMap" or "two-way dictionary", for .NET Standard 2.0 and higher.
using System.Collections.Generic;
var countryCapitals = new BidirectionalDictionary<string, string>()
{
["Italy"] = "Rome",
["India"] = "New Delhi",
["USA"] = "Washington, D.C.",
};
Console.WriteLine(countryCapitals["Italy"]); // "Rome"
Console.WriteLine(countryCapitals.Inverse["Rome"]); // "Italy"You can expose a read-only view over an existing bidirectional dictionary, keeping inversion capabilities intact. The wrapper uses the same underlying data and blocks modifications through the read-only API.
From BidirectionalDictionary:
using System.Collections.Generic;
BidirectionalDictionary<Key, Value> bidirectionalDictionary = ...;
var readOnly = bidirectionalDictionary.AsReadOnly();From IBidirectionalDictionary:
using System.Collections.Generic;
using System.Collections.ObjectModel;
IBidirectionalDictionary<Key, Value> bidirectionalDictionary = ...;
var readOnly = new ReadOnlyBidirectionalDictionary<Key, Value>(dictionary);To support abstraction-friendly code, the package exposes two interfaces:
IBidirectionalDictionaryIReadOnlyBidirectionalDictionary
Both BidirectionalDictionary and ReadOnlyBidirectionalDictionary implement these interfaces,
so you can depend on contracts instead of concrete types when needed.
The package includes LINQ-extensions to create a BidirectionalDictionary directly from sequences.
From KeyValuePair<TKey, TValue>:
using System.Linq;
IEnumerable<KeyValuePair<int, string>> source = new[]
{
new KeyValuePair<int, string>(1, "one"),
new KeyValuePair<int, string>(2, "two")
};
var bidirectionalDictionary = source.ToBidirectionalDictionary();From tuple sequence:
using System.Linq;
IEnumerable<(string Key, string Value)> source = new[]
{
(Key: "US", Value: "United States"),
(Key: "IT", Value: "Italy")
};
var bidirectionalDictionary = source.ToBidirectionalDictionary();From arbitrary source with selectors:
using System.Linq;
var users = new[]
{
new { Id = 10, Email = "[email protected]" },
new { Id = 20, Email = "[email protected]" }
};
var bidirectionalDictionary = users.ToBidirectionalDictionary(user => user.Id, user => user.Email);You can also pass custom comparers via overloads with keyComparer and valueComparer.
The library is licensed under the MIT license.