Skip to content

Commit 5aff6e9

Browse files
committed
Refactor extension methods in PointExtensions, DictionaryExtensions, and NumberExtensions for improved readability and usability
1 parent 7fe7fdc commit 5aff6e9

4 files changed

Lines changed: 192 additions & 196 deletions

File tree

DotNetExtensions/Collections/DictionaryExtensions.cs

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,65 +9,63 @@ namespace DotNetExtensions.Collections;
99
/// </summary>
1010
public static class DictionaryExtensions
1111
{
12-
/// <summary>
13-
/// Gets the value associated with the specified key in the dictionary.
14-
/// If the key does not exist, the provided value is added to the dictionary
15-
/// and returned.
16-
/// </summary>
12+
/// <param name="dictionary">The dictionary to search for the key and add the value if it does not exist.</param>
1713
/// <typeparam name="TKey">The type of the keys in the dictionary. Must be non-nullable.</typeparam>
1814
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
19-
/// <param name="dictionary">The dictionary to search for the key and add the value if it does not exist.</param>
20-
/// <param name="key">The key of the element to retrieve or add.</param>
21-
/// <param name="value">
22-
/// The value to add to the dictionary if the key does not exist.
23-
/// If the key exists, this value is ignored.
24-
/// </param>
25-
/// <returns>
26-
/// The value associated with the specified key if it exists in the dictionary,
27-
/// or the newly added value if the key was not present.
28-
/// </returns>
29-
/// <exception cref="ArgumentNullException">
30-
/// Thrown if <paramref name="dictionary"/> or <paramref name="key"/> is <c>null</c>.
31-
/// </exception>
32-
[return: NotNullIfNotNull(nameof(value))]
33-
public static TValue? GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
34-
where TKey : notnull
15+
extension<TKey, TValue>(Dictionary<TKey, TValue> dictionary) where TKey : notnull
3516
{
36-
ArgumentNullException.ThrowIfNull(dictionary);
37-
ArgumentNullException.ThrowIfNull(key);
17+
/// <summary>
18+
/// Gets the value associated with the specified key in the dictionary.
19+
/// If the key does not exist, the provided value is added to the dictionary
20+
/// and returned.
21+
/// </summary>
22+
/// <param name="key">The key of the element to retrieve or add.</param>
23+
/// <param name="value">
24+
/// The value to add to the dictionary if the key does not exist.
25+
/// If the key exists, this value is ignored.
26+
/// </param>
27+
/// <returns>
28+
/// The value associated with the specified key if it exists in the dictionary,
29+
/// or the newly added value if the key was not present.
30+
/// </returns>
31+
/// <exception cref="ArgumentNullException">
32+
/// Thrown if <paramref name="dictionary"/> or <paramref name="key"/> is <c>null</c>.
33+
/// </exception>
34+
[return: NotNullIfNotNull(nameof(value))]
35+
public TValue? GetOrAdd(TKey key, TValue value)
36+
{
37+
ArgumentNullException.ThrowIfNull(dictionary);
38+
ArgumentNullException.ThrowIfNull(key);
3839

39-
ref var val = ref CollectionsMarshal.GetValueRefOrAddDefault(dictionary, key, out var exists);
40-
if (!exists) val = value;
40+
ref var val = ref CollectionsMarshal.GetValueRefOrAddDefault(dictionary, key, out var exists);
41+
if (!exists) val = value;
4142

42-
return val;
43-
}
43+
return val;
44+
}
4445

45-
/// <summary>
46-
/// Attempts to update the value associated with the specified key in the dictionary.
47-
/// If the key does not exist, no changes are made, and the method returns <c>false</c>.
48-
/// </summary>
49-
/// <typeparam name="TKey">The type of the keys in the dictionary. Must be non-nullable.</typeparam>
50-
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
51-
/// <param name="dictionary">The dictionary to update the value in.</param>
52-
/// <param name="key">The key of the element to update.</param>
53-
/// <param name="value">The new value to set if the key exists in the dictionary.</param>
54-
/// <returns>
55-
/// <c>true</c> if the key exists and the value was updated; otherwise, <c>false</c>.
56-
/// </returns>
57-
/// <exception cref="ArgumentNullException">
58-
/// Thrown if <paramref name="dictionary"/> or <paramref name="key"/> is <c>null</c>.
59-
/// </exception>
60-
public static bool TryUpdate<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
61-
where TKey : notnull
62-
{
63-
ArgumentNullException.ThrowIfNull(dictionary);
64-
ArgumentNullException.ThrowIfNull(key);
46+
/// <summary>
47+
/// Attempts to update the value associated with the specified key in the dictionary.
48+
/// If the key does not exist, no changes are made, and the method returns <c>false</c>.
49+
/// </summary>
50+
/// <param name="key">The key of the element to update.</param>
51+
/// <param name="value">The new value to set if the key exists in the dictionary.</param>
52+
/// <returns>
53+
/// <c>true</c> if the key exists and the value was updated; otherwise, <c>false</c>.
54+
/// </returns>
55+
/// <exception cref="ArgumentNullException">
56+
/// Thrown if <paramref name="dictionary"/> or <paramref name="key"/> is <c>null</c>.
57+
/// </exception>
58+
public bool TryUpdate(TKey key, TValue value)
59+
{
60+
ArgumentNullException.ThrowIfNull(dictionary);
61+
ArgumentNullException.ThrowIfNull(key);
6562

66-
ref var val = ref CollectionsMarshal.GetValueRefOrNullRef(dictionary, key);
67-
if (Unsafe.IsNullRef(ref val))
68-
return false;
63+
ref var val = ref CollectionsMarshal.GetValueRefOrNullRef(dictionary, key);
64+
if (Unsafe.IsNullRef(ref val))
65+
return false;
6966

70-
val = value;
71-
return true;
67+
val = value;
68+
return true;
69+
}
7270
}
7371
}

DotNetExtensions/Core/NumberExtensions.cs

Lines changed: 86 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,112 +7,109 @@ namespace DotNetExtensions.Core;
77
/// </summary>
88
public static class NumberExtensions
99
{
10-
/// <summary>
11-
/// Calculates the number of digits in the given number, in base 10.
12-
/// </summary>
13-
/// <typeparam name="T">The numeric type implementing <see cref="INumber{T}"/>.</typeparam>
1410
/// <param name="number">The number to analyze.</param>
15-
/// <returns>The number of digits in the number.</returns>
16-
/// <remarks>
17-
/// For negative numbers, the sign is ignored, and the count includes all digits of the absolute value.
18-
/// </remarks>
19-
public static int NumberOfDigits<T>(this T number) where T : IBinaryInteger<T>
11+
/// <typeparam name="T">The numeric type implementing <see cref="INumber{T}"/>.</typeparam>
12+
extension<T>(T number) where T : IBinaryInteger<T>
2013
{
21-
if (number == T.Zero)
22-
return 1;
23-
24-
var ten = T.CreateChecked(10);
25-
var count = 0;
26-
while (number != T.Zero)
14+
/// <summary>
15+
/// Calculates the number of digits in the given number, in base 10.
16+
/// </summary>
17+
/// <returns>The number of digits in the number.</returns>
18+
/// <remarks>
19+
/// For negative numbers, the sign is ignored, and the count includes all digits of the absolute value.
20+
/// </remarks>
21+
public int NumberOfDigits()
2722
{
28-
number /= ten;
29-
count++;
30-
}
23+
if (number == T.Zero)
24+
return 1;
3125

32-
return count;
33-
}
34-
35-
/// <summary>
36-
/// Determines whether the given number is a palindrome.
37-
/// </summary>
38-
/// <typeparam name="T">The numeric type implementing <see cref="IBinaryInteger{T}"/>.</typeparam>
39-
/// <param name="number">The number to check.</param>
40-
/// <returns><c>true</c> if the number is a palindrome; otherwise, <c>false</c>.</returns>
41-
/// <remarks>
42-
/// Negative numbers are not considered palindromes.
43-
/// </remarks>
44-
public static bool IsPalindrome<T>(this T number) where T : IBinaryInteger<T>
45-
{
46-
if (number < T.Zero)
47-
return false;
26+
var ten = T.CreateChecked(10);
27+
var count = 0;
28+
while (number != T.Zero)
29+
{
30+
number /= ten;
31+
count++;
32+
}
4833

49-
try
50-
{
51-
return number == number.Reverse();
34+
return count;
5235
}
53-
catch (OverflowException)
36+
37+
/// <summary>
38+
/// Determines whether the given number is a palindrome.
39+
/// </summary>
40+
/// <returns><c>true</c> if the number is a palindrome; otherwise, <c>false</c>.</returns>
41+
/// <remarks>
42+
/// Negative numbers are not considered palindromes.
43+
/// </remarks>
44+
public bool IsPalindrome()
5445
{
55-
// If the number is too large to reverse, it can't be a palindrome.
56-
return false;
57-
}
58-
}
46+
if (number < T.Zero)
47+
return false;
5948

60-
/// <summary>
61-
/// Reverses the digits of the given number.
62-
/// </summary>
63-
/// <typeparam name="T">The numeric type implementing <see cref="IBinaryInteger{T}"/>.</typeparam>
64-
/// <param name="number">The number to reverse.</param>
65-
/// <returns>The reversed number.</returns>
66-
/// <remarks>
67-
/// For single-digit numbers, the result is the number itself.
68-
/// </remarks>
69-
/// <exception cref="OverflowException">
70-
/// Thrown if reversing the number causes an overflow.
71-
/// </exception>
72-
public static T Reverse<T>(this T number) where T : IBinaryInteger<T>
73-
{
74-
var ten = T.CreateChecked(10);
49+
try
50+
{
51+
return number == number.Reverse();
52+
}
53+
catch (OverflowException)
54+
{
55+
// If the number is too large to reverse, it can't be a palindrome.
56+
return false;
57+
}
58+
}
7559

76-
var reverse = T.Zero;
77-
while (number != T.Zero)
60+
/// <summary>
61+
/// Reverses the digits of the given number.
62+
/// </summary>
63+
/// <returns>The reversed number.</returns>
64+
/// <remarks>
65+
/// For single-digit numbers, the result is the number itself.
66+
/// </remarks>
67+
/// <exception cref="OverflowException">
68+
/// Thrown if reversing the number causes an overflow.
69+
/// </exception>
70+
public T Reverse()
7871
{
79-
checked
72+
var ten = T.CreateChecked(10);
73+
74+
var reverse = T.Zero;
75+
while (number != T.Zero)
8076
{
81-
reverse = reverse * ten + number % ten;
77+
checked
78+
{
79+
reverse = reverse * ten + number % ten;
80+
}
81+
82+
number /= ten;
8283
}
8384

84-
number /= ten;
85+
return reverse;
8586
}
8687

87-
return reverse;
88-
}
89-
90-
/// <summary>
91-
/// Splits the given number into two parts: left and right.
92-
/// </summary>
93-
/// <typeparam name="T">The numeric type implementing <see cref="INumber{T}"/>.</typeparam>
94-
/// <param name="number">The number to split.</param>
95-
/// <returns>
96-
/// A tuple containing the left and right parts of the number.
97-
/// </returns>
98-
/// <remarks>
99-
/// The number is split based on the number of digits, with the left part containing
100-
/// the most significant digits and the right part containing the least significant digits.
101-
/// </remarks>
102-
/// <exception cref="ArgumentOutOfRangeException">
103-
/// Thrown if the number is negative.
104-
/// </exception>
105-
public static (T Left, T Right) Split<T>(this T number) where T : IBinaryInteger<T>
106-
{
107-
ArgumentOutOfRangeException.ThrowIfNegative(number);
88+
/// <summary>
89+
/// Splits the given number into two parts: left and right.
90+
/// </summary>
91+
/// <returns>
92+
/// A tuple containing the left and right parts of the number.
93+
/// </returns>
94+
/// <remarks>
95+
/// The number is split based on the number of digits, with the left part containing
96+
/// the most significant digits and the right part containing the least significant digits.
97+
/// </remarks>
98+
/// <exception cref="ArgumentOutOfRangeException">
99+
/// Thrown if the number is negative.
100+
/// </exception>
101+
public (T Left, T Right) Split()
102+
{
103+
ArgumentOutOfRangeException.ThrowIfNegative(number);
108104

109-
var numDigits = number.NumberOfDigits();
110-
var halfDigits = numDigits / 2 + numDigits % 2;
111-
var divisor = T.CreateChecked(Math.Pow(10, halfDigits));
105+
var numDigits = number.NumberOfDigits();
106+
var halfDigits = numDigits / 2 + numDigits % 2;
107+
var divisor = T.CreateChecked(Math.Pow(10, halfDigits));
112108

113-
var leftPart = number / divisor;
114-
var rightPart = number % divisor;
109+
var leftPart = number / divisor;
110+
var rightPart = number % divisor;
115111

116-
return (leftPart, rightPart);
112+
return (leftPart, rightPart);
113+
}
117114
}
118115
}

0 commit comments

Comments
 (0)