-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added misc extension methods IDictionary<object, object?>
+ added .NET 6 unit test project
- Loading branch information
Showing
5 changed files
with
370 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
204 changes: 204 additions & 0 deletions
204
src/Skybrud.Essentials/Collections/Extensions/DictionaryExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
|
||
namespace Skybrud.Essentials.Collections.Extensions { | ||
|
||
/// <summary> | ||
/// Static class with various dictionary related extension methods. | ||
/// </summary> | ||
public static class DictionaryExtensions { | ||
|
||
/// <summary> | ||
/// Returns the 32-bit integer value of the dictionary item with the specified <paramref name="key"/>. If a | ||
/// matching dictionary doesn't exist or it's value can not be converted to a <see cref="int"/> value, <c>0</c> | ||
/// is returned instead. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <returns>The <see cref="int"/> value if successful; otherwise, <c>0</c>.</returns> | ||
public static int GetInt32(this IDictionary<object, object?>? dictionary, object key) { | ||
return TryGetInt32(dictionary, key, out int result) ? result : 0; | ||
} | ||
|
||
/// <summary> | ||
/// Returns the 32-bit integer value of the dictionary item with the specified <paramref name="key"/>. If a | ||
/// matching dictionary doesn't exist or it's value can not be converted to a <see cref="int"/> value, | ||
/// <see langword="null"/> is returned instead. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <returns>The <see cref="int"/> value if successful; otherwise, <see langword="null"/>.</returns> | ||
public static int? GetInt32OrNull(this IDictionary<object, object?>? dictionary, object key) { | ||
return TryGetInt32(dictionary, key, out int? result) ? result : null; | ||
} | ||
|
||
/// <summary> | ||
/// Returns the 64-bit integer value of the dictionary item with the specified <paramref name="key"/>. If a | ||
/// matching dictionary doesn't exist or it's value can not be converted to a <see cref="long"/> value, <c>0</c> | ||
/// is returned instead. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <returns>The <see cref="long"/> value if successful; otherwise, <c>0</c>.</returns> | ||
public static long GetInt64(this IDictionary<object, object?>? dictionary, object key) { | ||
return TryGetInt64(dictionary, key, out long result) ? result : 0; | ||
} | ||
|
||
/// <summary> | ||
/// Returns the 64-bit integer value of the dictionary item with the specified <paramref name="key"/>. If a | ||
/// matching dictionary doesn't exist or it's value can not be converted to a <see cref="long"/> value, | ||
/// <see langword="null"/> is returned instead. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <returns>The <see cref="long"/> value if successful; otherwise, <see langword="null"/>.</returns> | ||
public static long? GetInt64OrNull(this IDictionary<object, object?>? dictionary, object key) { | ||
return TryGetInt64(dictionary, key, out long? result) ? result : null; | ||
} | ||
|
||
/// <summary> | ||
/// Returns the string value of the dictionary item with the specified <paramref name="key"/>. If a matching dictionary item is found, but the value isn't a <see cref="string"/>, the value s converted to it's culture invariant string representation. If a matching dictionary isn't found, <see langword="null"/> is returned instead. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <returns>The <see cref="string"/> value if successful; otherwise, <see langword="null"/>.</returns> | ||
public static string? GetString(this IDictionary<object, object?>? dictionary, object key) { | ||
return TryGetString(dictionary, key, out string? result) ? result : null; | ||
} | ||
|
||
/// <summary> | ||
/// Attempts to get a 32-bit integer value (<see cref="int"/>) from the with the specified <paramref name="key"/>. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <param name="result">When this method returns, holds the <see cref="int"/> value if successful; otherwise, <c>0</c>.</param> | ||
/// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns> | ||
public static bool TryGetInt32(this IDictionary<object, object?>? dictionary, object key, out int result) { | ||
|
||
if (dictionary is null || !dictionary.TryGetValue(key, out object? value)) { | ||
result = default; | ||
return false; | ||
} | ||
|
||
switch (value) { | ||
|
||
case int number: | ||
result = number; | ||
return true; | ||
|
||
case long longValue: | ||
if (longValue is >= int.MinValue and <= int.MaxValue) { | ||
result = (int) longValue; | ||
return true; | ||
} | ||
result = default; | ||
return false; | ||
|
||
case string str: | ||
return int.TryParse(str, out result); | ||
|
||
default: | ||
result = default; | ||
return false; | ||
|
||
} | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Attempts to get a 32-bit integer value (<see cref="int"/>) from the with the specified <paramref name="key"/>. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <param name="result">When this method returns, holds the <see cref="int"/> value if successful; otherwise, <see langword="null"/>.</param> | ||
/// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns> | ||
public static bool TryGetInt32(this IDictionary<object, object?>? dictionary, object key, [NotNullWhen(true)] out int? result) { | ||
|
||
if (TryGetInt32(dictionary, key, out int value)) { | ||
result = value; | ||
return true; | ||
} | ||
|
||
result = null; | ||
return false; | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Attempts to get a 64-bit integer value (<see cref="long"/>) from the with the specified <paramref name="key"/>. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <param name="result">When this method returns, holds the <see cref="long"/> value if successful; otherwise, <c>0</c>.</param> | ||
/// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns> | ||
public static bool TryGetInt64(this IDictionary<object, object?>? dictionary, object key, out long result) { | ||
|
||
if (dictionary is null || !dictionary.TryGetValue(key, out object? value)) { | ||
result = default; | ||
return false; | ||
} | ||
|
||
switch (value) { | ||
|
||
case int intValue: | ||
result = intValue; | ||
return true; | ||
|
||
case long longValue: | ||
result = longValue; | ||
return true; | ||
|
||
case string str: | ||
return long.TryParse(str, default, CultureInfo.InvariantCulture, out result); | ||
|
||
default: | ||
result = default; | ||
return false; | ||
|
||
} | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Attempts to get a 64-bit integer value (<see cref="int"/>) from the with the specified <paramref name="key"/>. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <param name="result">When this method returns, holds the <see cref="long"/> value if successful; otherwise, <see langword="null"/>.</param> | ||
/// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns> | ||
public static bool TryGetInt64(this IDictionary<object, object?>? dictionary, object key, [NotNullWhen(true)] out long? result) { | ||
|
||
if (TryGetInt64(dictionary, key, out long value)) { | ||
result = value; | ||
return true; | ||
} | ||
|
||
result = null; | ||
return false; | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Attempts to get the string value with the specified <paramref name="key"/>. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary.</param> | ||
/// <param name="key">The key of the dictionary item.</param> | ||
/// <param name="result">When this method returns, holds the <see cref="string"/> value if successful; otherwise, <see langword="null"/>.</param> | ||
/// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns> | ||
public static bool TryGetString(this IDictionary<object, object?>? dictionary, object key, [NotNullWhen(true)] out string? result) { | ||
|
||
if (dictionary is null || !dictionary.TryGetValue(key, out object? value)) { | ||
result = null; | ||
return false; | ||
} | ||
|
||
result = string.Format(CultureInfo.InvariantCulture, "{0}", value); | ||
return true; | ||
|
||
|
||
} | ||
|
||
} | ||
|
||
} |
135 changes: 135 additions & 0 deletions
135
src/TestProject1/Collections/DictionaryExtensionsTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
| ||
using Skybrud.Essentials.Collections.Extensions; | ||
|
||
namespace TestProject1.Collections { | ||
|
||
[TestClass] | ||
public class DictionaryExtensionsTests { | ||
|
||
[TestMethod] | ||
public void GetInt32() { | ||
|
||
Dictionary<object, object?> dictionary = new() { | ||
{"number", 123}, | ||
{"long", 123L}, | ||
{"longMax", long.MaxValue}, | ||
{"string", "123"}, | ||
{"null", null} | ||
}; | ||
|
||
int a = dictionary.GetInt32("number"); | ||
Assert.AreEqual(123, a, "#A"); | ||
|
||
int b = dictionary.GetInt32("long"); | ||
Assert.AreEqual(123, b, "#B"); | ||
|
||
int c = dictionary.GetInt32("longMax"); | ||
Assert.AreEqual(0, c, "#C"); | ||
|
||
int d = dictionary.GetInt32("string"); | ||
Assert.AreEqual(123, d, "#D"); | ||
|
||
int e = dictionary.GetInt32("null"); | ||
Assert.AreEqual(0, e, "#E"); | ||
|
||
int f = dictionary.GetInt32("nope"); | ||
Assert.AreEqual(0, f, "#F"); | ||
|
||
} | ||
|
||
[TestMethod] | ||
public void GetInt32OrNull() { | ||
|
||
Dictionary<object, object?> dictionary = new() { | ||
{"number", 123}, | ||
{"long", 123L}, | ||
{"longMax", long.MaxValue}, | ||
{"string", "123"}, | ||
{"null", null} | ||
}; | ||
|
||
int? a = dictionary.GetInt32OrNull("number"); | ||
Assert.AreEqual(123, a, "#A"); | ||
|
||
int? b = dictionary.GetInt32OrNull("long"); | ||
Assert.AreEqual(123, b, "#B"); | ||
|
||
int? c = dictionary.GetInt32OrNull("longMax"); | ||
Assert.AreEqual(null, c, "#C"); | ||
|
||
int? d = dictionary.GetInt32OrNull("string"); | ||
Assert.AreEqual(123, d, "#D"); | ||
|
||
int? e = dictionary.GetInt32OrNull("null"); | ||
Assert.AreEqual(null, e, "#E"); | ||
|
||
int? f = dictionary.GetInt32OrNull("nope"); | ||
Assert.AreEqual(null, f, "#F"); | ||
|
||
} | ||
|
||
[TestMethod] | ||
public void GetInt64() { | ||
|
||
Dictionary<object, object?> dictionary = new() { | ||
{"number", 123}, | ||
{"long", 123L}, | ||
{"longMax", long.MaxValue}, | ||
{"string", "123"}, | ||
{"null", null} | ||
}; | ||
|
||
long a = dictionary.GetInt64("number"); | ||
Assert.AreEqual(123, a, "#A"); | ||
|
||
long b = dictionary.GetInt64("long"); | ||
Assert.AreEqual(123, b, "#B"); | ||
|
||
long c = dictionary.GetInt64("longMax"); | ||
Assert.AreEqual(long.MaxValue, c, "#C"); | ||
|
||
long d = dictionary.GetInt64("string"); | ||
Assert.AreEqual(123, d, "#D"); | ||
|
||
long e = dictionary.GetInt64("null"); | ||
Assert.AreEqual(0, e, "#E"); | ||
|
||
long f = dictionary.GetInt64("nope"); | ||
Assert.AreEqual(0, f, "#F"); | ||
|
||
} | ||
|
||
[TestMethod] | ||
public void GetInt64OrNull() { | ||
|
||
Dictionary<object, object?> dictionary = new() { | ||
{"number", 123}, | ||
{"long", 123L}, | ||
{"longMax", long.MaxValue}, | ||
{"string", "123"}, | ||
{"null", null} | ||
}; | ||
|
||
long? a = dictionary.GetInt64OrNull("number"); | ||
Assert.AreEqual(123, a, "#A"); | ||
|
||
long? b = dictionary.GetInt64OrNull("long"); | ||
Assert.AreEqual(123, b, "#B"); | ||
|
||
long? c = dictionary.GetInt64OrNull("longMax"); | ||
Assert.AreEqual(long.MaxValue, c, "#C"); | ||
|
||
long? d = dictionary.GetInt64OrNull("string"); | ||
Assert.AreEqual(123, d, "#D"); | ||
|
||
long? e = dictionary.GetInt64OrNull("null"); | ||
Assert.AreEqual(null, e, "#E"); | ||
|
||
long? f = dictionary.GetInt64OrNull("nope"); | ||
Assert.AreEqual(null, f, "#E"); | ||
|
||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" /> | ||
<PackageReference Include="coverlet.collector" Version="3.1.2" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Skybrud.Essentials\Skybrud.Essentials.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
global using Microsoft.VisualStudio.TestTools.UnitTesting; |