Skip to content

Commit b25e281

Browse files
committed
Added support for nullable reference types
- Added .NET 5.0 and .NET 6.0 as additional target frameworks - Installed "Nullable" NuGet package as private dependency to allow code analysis for older .NET versions
1 parent 8e75a29 commit b25e281

File tree

103 files changed

+1650
-1591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1650
-1591
lines changed

src/Skybrud.Essentials/Collections/ArrayUtils.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
// ReSharper disable UseArrayEmptyMethod
22

3+
using System;
4+
using System.Reflection;
5+
36
namespace Skybrud.Essentials.Collections {
47

58
/// <summary>
69
/// Static class with various logic for working with arrays.
710
/// </summary>
811
public static class ArrayUtils {
912

10-
#if NET46_OR_GREATER || NETSTANDARD1_3_OR_GREATER
13+
/// <summary>
14+
/// Returns an empty array of the specified <paramref name="type"/>.
15+
/// </summary>
16+
/// <param name="type">The type of the items in the array.</param>
17+
/// <returns>An array of <paramref name="type"/>.</returns>
18+
public static Array Empty(Type type) {
19+
return (Array) typeof(ArrayUtils)
20+
.GetTypeInfo()
21+
.GetDeclaredMethod("Empty")!
22+
.MakeGenericMethod(type)
23+
.Invoke(null, null)!;
24+
}
25+
26+
#if NET46_OR_GREATER || NETSTANDARD1_3_OR_GREATER || NET5_0_OR_GREATER
1127

1228

1329
/// <summary>
@@ -19,11 +35,13 @@ public static class ArrayUtils {
1935
/// <cref>https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=net-6.0</cref>
2036
/// </see>
2137
public static T[] Empty<T>() {
22-
return System.Array.Empty<T>();
38+
return Array.Empty<T>();
2339
}
2440

2541
#else
2642

43+
#pragma warning disable CA1825 // Avoid zero-length array allocations
44+
2745
/// <summary>
2846
/// Returns an empty array.
2947
/// </summary>

src/Skybrud.Essentials/Collections/Extensions/EnumerableExtensions.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TS
3939
/// <see>
4040
/// <cref>https://github.com/dotnet/runtime/blob/v6.0.4/src/libraries/System.Linq/src/System/Linq/Distinct.cs#L48</cref>
4141
/// </see>
42-
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) {
42+
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer) {
4343
if (source is null) throw new ArgumentNullException(nameof(source));
4444
if (keySelector is null) throw new ArgumentNullException(nameof(keySelector));
4545
return DistinctByIterator(source, keySelector, comparer);
@@ -48,7 +48,7 @@ public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TS
4848
/// <see>
4949
/// <cref>https://github.com/dotnet/runtime/blob/v6.0.4/src/libraries/System.Linq/src/System/Linq/Distinct.cs#L62</cref>
5050
/// </see>
51-
private static IEnumerable<TSource> DistinctByIterator<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) {
51+
private static IEnumerable<TSource> DistinctByIterator<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer) {
5252

5353
using IEnumerator<TSource> enumerator = source.GetEnumerator();
5454

@@ -82,7 +82,7 @@ public static IEnumerable<IEnumerable<TSource>> InGroupsOf<TSource>(this IEnumer
8282
if (source == null) throw new ArgumentNullException(nameof(source));
8383
if (groupSize <= 0) throw new ArgumentException("Must be greater than zero.", nameof(groupSize));
8484

85-
TSource[] temp = null;
85+
TSource[]? temp = null;
8686
var count = 0;
8787

8888
foreach (var item in source) {
@@ -138,7 +138,7 @@ public static IOrderedEnumerable<T> OrderBy<T, TKey>(this IEnumerable<T> collect
138138
/// <param name="comparer">An <see cref="IComparer{T}"/> to compare the keys.</param>
139139
/// <param name="reverse">Whether <paramref name="source"/> should be sorted in descending order.</param>
140140
/// <returns>An instanced of <see cref="IOrderedEnumerable{T}"/>.</returns>
141-
public static IOrderedEnumerable<T> OrderBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> func, IComparer<TKey> comparer, bool reverse) {
141+
public static IOrderedEnumerable<T> OrderBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> func, IComparer<TKey>? comparer, bool reverse) {
142142
return reverse ? source.OrderByDescending(func, comparer) : source.OrderBy(func, comparer);
143143
}
144144

@@ -153,7 +153,7 @@ public static IOrderedEnumerable<T> OrderBy<T, TKey>(this IEnumerable<T> source,
153153
/// <param name="comparer">An <see cref="IComparer{T}"/> to compare the keys.</param>
154154
/// <param name="order">The order by which the collection should be sorted.</param>
155155
/// <returns>An instanced of <see cref="IOrderedEnumerable{T}"/>.</returns>
156-
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer, SortOrder order) {
156+
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey>? comparer, SortOrder order) {
157157
return order == SortOrder.Descending ? source.OrderByDescending(keySelector, comparer) : source.OrderBy(keySelector, comparer);
158158
}
159159

@@ -166,8 +166,8 @@ public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerabl
166166
/// <see>
167167
/// <cref>https://github.com/umbraco/Umbraco-CMS/blob/v9/contrib/src/Umbraco.Core/Extensions/EnumerableExtensions.cs#L226</cref>
168168
/// </see>
169-
public static IEnumerable<TSource> WhereNotNull<TSource>(this IEnumerable<TSource> source) where TSource : class {
170-
return source.Where(x => x != null);
169+
public static IEnumerable<TSource> WhereNotNull<TSource>(this IEnumerable<TSource?> source) where TSource : class {
170+
return source.Where(x => x != null)!;
171171
}
172172

173173
/// <summary>
@@ -180,9 +180,9 @@ public static IEnumerable<TSource> WhereNotNull<TSource>(this IEnumerable<TSourc
180180
public static IEnumerable Cast(this IEnumerable source, Type targetType) {
181181
return (IEnumerable) typeof(Enumerable)
182182
.GetTypeInfo()
183-
.GetDeclaredMethod("Cast")
183+
.GetDeclaredMethod("Cast")!
184184
.MakeGenericMethod(targetType)
185-
.Invoke(null, new object[] { source });
185+
.Invoke(null, new object[] { source })!;
186186
}
187187

188188
/// <summary>
@@ -194,9 +194,9 @@ public static IEnumerable Cast(this IEnumerable source, Type targetType) {
194194
public static IList ToList(this IEnumerable source, Type targetType) {
195195
return (IList) typeof(Enumerable)
196196
.GetTypeInfo()
197-
.GetDeclaredMethod("ToList")
197+
.GetDeclaredMethod("ToList")!
198198
.MakeGenericMethod(targetType)
199-
.Invoke(null, new object[] { source });
199+
.Invoke(null, new object[] { source })!;
200200
}
201201

202202
/// <summary>
@@ -208,9 +208,9 @@ public static IList ToList(this IEnumerable source, Type targetType) {
208208
public static Array ToArray(this IEnumerable source, Type targetType) {
209209
return (Array) typeof(Enumerable)
210210
.GetTypeInfo()
211-
.GetDeclaredMethod("ToArray")
211+
.GetDeclaredMethod("ToArray")!
212212
.MakeGenericMethod(targetType)
213-
.Invoke(null, new object[] { source });
213+
.Invoke(null, new object[] { source })!;
214214
}
215215

216216
/// <summary>
@@ -234,7 +234,7 @@ public static HashSet<TResult> ToHashSet<TSource, TResult>(this IEnumerable<TSou
234234
/// <param name="selector">A function to extract a key from each element.</param>
235235
/// <param name="comparer">The <see cref="IEqualityComparer{T}"/> implementation to use when comparing values in the set, or null to use the default <see cref="EqualityComparer{T}"/> implementation for the set type.</param>
236236
/// <returns>A <see cref="HashSet{TResult}"/> that contains values of type <typeparamref name="TResult"/> selected from the input sequence.</returns>
237-
public static HashSet<TResult> ToHashSet<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, IEqualityComparer<TResult> comparer) {
237+
public static HashSet<TResult> ToHashSet<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, IEqualityComparer<TResult>? comparer) {
238238
return new HashSet<TResult>(source.Select(selector), comparer);
239239
}
240240

@@ -256,7 +256,7 @@ public static SortOrder GetReverse(this SortOrder order) {
256256
/// otherwise, the default value of <typeparamref name="T"/>.</param>
257257
/// <param name="second">When this method returns, holds the second item if the collection has at least two
258258
/// items; otherwise, the default value of <typeparamref name="T"/>.</param>
259-
public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, out T second) {
259+
public static void Deconstruct<T>(this IEnumerable<T> collection, out T? first, out T? second) {
260260

261261
first = default;
262262
second = default;
@@ -293,7 +293,7 @@ public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, o
293293
/// items; otherwise, the default value of <typeparamref name="T"/>.</param>
294294
/// <param name="third">When this method returns, holds the third item if the collection has at least three
295295
/// items; otherwise, the default value of <typeparamref name="T"/>.</param>
296-
public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, out T second, out T third) {
296+
public static void Deconstruct<T>(this IEnumerable<T> collection, out T? first, out T? second, out T? third) {
297297

298298
first = default;
299299
second = default;
@@ -325,7 +325,7 @@ public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, o
325325
/// items; otherwise, the default value of <typeparamref name="T"/>.</param>
326326
/// <param name="fourth">When this method returns, holds the fourth item if the collection has at least four
327327
/// items; otherwise, the default value of <typeparamref name="T"/>.</param>
328-
public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, out T second, out T third, out T fourth) {
328+
public static void Deconstruct<T>(this IEnumerable<T> collection, out T? first, out T? second, out T? third, out T? fourth) {
329329

330330
first = default;
331331
second = default;
@@ -355,7 +355,7 @@ public static void Deconstruct<T>(this IEnumerable<T> collection, out T first, o
355355
/// <remarks>
356356
/// <para>The implementation of this method uses <see cref="Guid.NewGuid"/> for sorting the items in a random order. When testing various implementions, this seems to be the most random.</para>
357357
/// </remarks>
358-
public static TSource RandomOrDefault<TSource>(this IEnumerable<TSource> collection) {
358+
public static TSource? RandomOrDefault<TSource>(this IEnumerable<TSource> collection) {
359359
return collection.OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
360360
}
361361

0 commit comments

Comments
 (0)