diff --git a/src/OptionalValues/Extensions/DictionaryExtensions.cs b/src/OptionalValues/Extensions/DictionaryExtensions.cs
new file mode 100644
index 0000000..2998852
--- /dev/null
+++ b/src/OptionalValues/Extensions/DictionaryExtensions.cs
@@ -0,0 +1,64 @@
+namespace OptionalValues.Extensions;
+
+///
+/// Extension methods for .
+///
+public static class DictionaryExtensions
+{
+ ///
+ /// Gets the value associated with the specified key, returning if the key is not found.
+ ///
+ /// A specified when the key is found, or an when the key is not found.
+ public static OptionalValue GetOptionalValue(this IDictionary dictionary, TKey key)
+ {
+ ArgumentNullException.ThrowIfNull(dictionary);
+ ArgumentNullException.ThrowIfNull(key);
+
+ return dictionary.TryGetValue(key, out T? value) ? new OptionalValue(value) : OptionalValue.Unspecified;
+ }
+
+ ///
+ /// Adds the specified key and value to the dictionary if the value is specified.
+ ///
+ /// When value is specified and the key already exists in the dictionary.
+ /// The key is null.
+ public static void AddOptionalValue(this IDictionary dictionary, TKey key, OptionalValue value)
+ {
+ ArgumentNullException.ThrowIfNull(dictionary);
+ ArgumentNullException.ThrowIfNull(key);
+
+ if (value.IsSpecified)
+ {
+ dictionary.Add(key, value.SpecifiedValue);
+ }
+ }
+
+ ///
+ /// Adds the specified key and value to the dictionary if the value is specified.
+ ///
+ /// When value is specified and the key already exists in the dictionary.
+ /// The key is null.
+ /// if the value was added to the dictionary; otherwise when the already exists or the value is , .
+ public static bool TryAddOptionalValue(this IDictionary dictionary, TKey key, OptionalValue value)
+ {
+ ArgumentNullException.ThrowIfNull(dictionary);
+ ArgumentNullException.ThrowIfNull(key);
+
+ return value.IsSpecified && dictionary.TryAdd(key, value.SpecifiedValue);
+ }
+
+ ///
+ /// Sets the specified key and value in the dictionary if the value is specified.
+ ///
+ /// The key is null.
+ public static void SetOptionalValue(this IDictionary dictionary, TKey key, OptionalValue value)
+ {
+ ArgumentNullException.ThrowIfNull(dictionary);
+ ArgumentNullException.ThrowIfNull(key);
+
+ if (value.IsSpecified)
+ {
+ dictionary[key] = value.SpecifiedValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OptionalValues/PublicAPI.Unshipped.txt b/src/OptionalValues/PublicAPI.Unshipped.txt
index 6459d04..aa77a42 100644
--- a/src/OptionalValues/PublicAPI.Unshipped.txt
+++ b/src/OptionalValues/PublicAPI.Unshipped.txt
@@ -1,6 +1,11 @@
+OptionalValues.Extensions.DictionaryExtensions
OptionalValues.OptionalValueJsonConverterAttribute
OptionalValues.OptionalValueJsonConverterAttribute.InnerConverterType.get -> System.Type?
OptionalValues.OptionalValueJsonConverterAttribute.OptionalValueJsonConverterAttribute() -> void
OptionalValues.OptionalValueJsonConverterAttribute.OptionalValueJsonConverterAttribute(System.Type! innerConverterType) -> void
override OptionalValues.OptionalValueJsonConverterAttribute.CreateConverter(System.Type! typeToConvert) -> System.Text.Json.Serialization.JsonConverter?
+static OptionalValues.Extensions.DictionaryExtensions.AddOptionalValue(this System.Collections.Generic.IDictionary! dictionary, TKey key, OptionalValues.OptionalValue value) -> void
+static OptionalValues.Extensions.DictionaryExtensions.GetOptionalValue(this System.Collections.Generic.IDictionary! dictionary, TKey key) -> OptionalValues.OptionalValue
+static OptionalValues.Extensions.DictionaryExtensions.SetOptionalValue(this System.Collections.Generic.IDictionary! dictionary, TKey key, OptionalValues.OptionalValue value) -> void
+static OptionalValues.Extensions.DictionaryExtensions.TryAddOptionalValue(this System.Collections.Generic.IDictionary! dictionary, TKey key, OptionalValues.OptionalValue value) -> bool
virtual OptionalValues.OptionalValueJsonConverterAttribute.CreateInnerConverter() -> System.Text.Json.Serialization.JsonConverter!
\ No newline at end of file
diff --git a/test/OptionalValues.Tests/Extensions/DictionaryExtensionsTest.cs b/test/OptionalValues.Tests/Extensions/DictionaryExtensionsTest.cs
new file mode 100644
index 0000000..1b2a314
--- /dev/null
+++ b/test/OptionalValues.Tests/Extensions/DictionaryExtensionsTest.cs
@@ -0,0 +1,295 @@
+using OptionalValues.Extensions;
+
+namespace OptionalValues.Tests.Extensions;
+
+public class DictionaryExtensionsTest
+{
+ public class GetOptionalValue : DictionaryExtensionsTest
+ {
+ [Fact]
+ public void ReturnsUnspecifiedWhenKeyIsNotFound()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ OptionalValue result = dictionary.GetOptionalValue("key");
+
+ // Assert
+ Assert.False(result.IsSpecified);
+ }
+
+ [Fact]
+ public void ReturnsSpecifiedValueWhenKeyIsFound()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ OptionalValue result = dictionary.GetOptionalValue("key");
+
+ // Assert
+ Assert.True(result.IsSpecified);
+ Assert.Equal(42, result.SpecifiedValue);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenDictionaryIsNull()
+ {
+ // Arrange
+ IDictionary dictionary = null!;
+
+ // Act
+ Action action = () => dictionary.GetOptionalValue("key");
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("dictionary", exception.ParamName);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenKeyIsNull()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ Action action = () => dictionary.GetOptionalValue(null!);
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("key", exception.ParamName);
+ }
+ }
+
+ public class AddOptionalValue : DictionaryExtensionsTest
+ {
+ [Fact]
+ public void AddsValueWhenSpecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ dictionary.AddOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ Assert.Equal(42, dictionary["key"]);
+ }
+
+ [Fact]
+ public void DoesNotAddValueWhenUnspecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ dictionary.AddOptionalValue("key", OptionalValue.Unspecified);
+
+ // Assert
+ Assert.Empty(dictionary);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenDictionaryIsNull()
+ {
+ // Arrange
+ IDictionary dictionary = null!;
+
+ // Act
+ Action action = () => dictionary.AddOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("dictionary", exception.ParamName);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenKeyIsNull()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ Action action = () => dictionary.AddOptionalValue(null!, new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("key", exception.ParamName);
+ }
+
+ [Fact]
+ public void ThrowsArgumentExceptionWhenKeyAlreadyExists()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ Action action = () => dictionary.AddOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ Assert.Throws(action);
+ }
+ }
+
+ public class TryAddOptionalValue : DictionaryExtensionsTest
+ {
+ [Fact]
+ public void AddsValueWhenSpecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ var result = dictionary.TryAddOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ Assert.True(result);
+ Assert.Equal(42, dictionary["key"]);
+ }
+
+ [Fact]
+ public void DoesNotAddValueWhenUnspecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ var result = dictionary.TryAddOptionalValue("key", OptionalValue.Unspecified);
+
+ // Assert
+ Assert.False(result);
+ Assert.Empty(dictionary);
+ }
+
+ [Fact]
+ public void DoesNotAddWhenKeyExists()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ var result = dictionary.TryAddOptionalValue("key", new OptionalValue(9000));
+
+ // Assert
+ Assert.False(result);
+ Assert.Equal(42, dictionary["key"]);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenDictionaryIsNull()
+ {
+ // Arrange
+ IDictionary dictionary = null!;
+
+ // Act
+ Action action = () => dictionary.TryAddOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("dictionary", exception.ParamName);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenKeyIsNull()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ Action action = () => dictionary.TryAddOptionalValue(null!, new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("key", exception.ParamName);
+ }
+ }
+
+ public class SetOptionalValue : DictionaryExtensionsTest
+ {
+ [Fact]
+ public void SetsValueWhenSpecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ dictionary.SetOptionalValue("key", new OptionalValue(9000));
+
+ // Assert
+ Assert.Equal(9000, dictionary["key"]);
+ }
+
+ [Fact]
+ public void DoesNotSetValueWhenUnspecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ dictionary.SetOptionalValue("key", OptionalValue.Unspecified);
+
+ // Assert
+ Assert.Equal(42, dictionary["key"]);
+ }
+
+ [Fact]
+ public void OverwritesValueWhenSpecified()
+ {
+ // Arrange
+ var dictionary = new Dictionary
+ {
+ ["key"] = 42
+ };
+
+ // Act
+ dictionary.SetOptionalValue("key", new OptionalValue(9000));
+
+ // Assert
+ Assert.Equal(9000, dictionary["key"]);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenDictionaryIsNull()
+ {
+ // Arrange
+ IDictionary dictionary = null!;
+
+ // Act
+ Action action = () => dictionary.SetOptionalValue("key", new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("dictionary", exception.ParamName);
+ }
+
+ [Fact]
+ public void ThrowsArgumentNullExceptionWhenKeyIsNull()
+ {
+ // Arrange
+ var dictionary = new Dictionary();
+
+ // Act
+ Action action = () => dictionary.SetOptionalValue(null!, new OptionalValue(42));
+
+ // Assert
+ ArgumentNullException exception = Assert.Throws(action);
+ Assert.Equal("key", exception.ParamName);
+ }
+ }
+}
\ No newline at end of file