diff --git a/SystemExtensions.NetStandard/Collections/AVLTree.cs b/SystemExtensions.NetStandard/Collections/AVLTree.cs index 2bc95f3..8595672 100644 --- a/SystemExtensions.NetStandard/Collections/AVLTree.cs +++ b/SystemExtensions.NetStandard/Collections/AVLTree.cs @@ -16,14 +16,14 @@ public sealed class AVLTree : ICollection where T : IComparable private class AVLNode { public TKey Value; - public AVLNode Left; - public AVLNode Right; + public AVLNode Left = default!; + public AVLNode Right = default!; public AVLNode(TKey value) { this.Value = value; } } - AVLNode root; + AVLNode root = default!; private int count = 0; private readonly bool isReadOnly = false; #endregion @@ -98,7 +98,7 @@ public sealed class AVLTree : ICollection where T : IComparable /// Value to be deleted. public bool Remove(T value) { - this.root = this.Delete(this.root, value); + this.root = this.Delete(this.root, value)!; return true; } /// @@ -115,19 +115,19 @@ public sealed class AVLTree : ICollection where T : IComparable if (currentNode.Left != null) { queue.Enqueue(currentNode.Left); - currentNode.Left = null; + currentNode.Left = default!; this.count--; } if (currentNode.Right != null) { queue.Enqueue(currentNode.Right); - currentNode.Right = null; + currentNode.Right = default!; this.count--; } } - this.root = null; + this.root = default!; this.count--; } /// @@ -222,9 +222,8 @@ public sealed class AVLTree : ICollection where T : IComparable return current; } - private AVLNode Delete(AVLNode current, T target) + private AVLNode? Delete(AVLNode current, T target) { - AVLNode parent; if (current == null) { return null; } else @@ -232,7 +231,7 @@ public sealed class AVLTree : ICollection where T : IComparable //left subtree if (target.CompareTo(current.Value) < 0) { - current.Left = this.Delete(current.Left, target); + current.Left = this.Delete(current.Left, target)!; if (this.BalanceFactor(current) == -2)//here { if (this.BalanceFactor(current.Right) <= 0) @@ -248,7 +247,7 @@ public sealed class AVLTree : ICollection where T : IComparable //right subtree else if (target.CompareTo(current.Value) > 0) { - current.Right = this.Delete(current.Right, target); + current.Right = this.Delete(current.Right, target)!; if (this.BalanceFactor(current) == 2) { if (this.BalanceFactor(current.Left) >= 0) @@ -268,14 +267,14 @@ public sealed class AVLTree : ICollection where T : IComparable if (current.Right != null) { //delete its inorder successor - parent = current.Right; + var parent = current.Right; while (parent.Left != null) { parent = parent.Left; } current.Value = parent.Value; - current.Right = this.Delete(current.Right, parent.Value); + current.Right = this.Delete(current.Right, parent.Value)!; if (this.BalanceFactor(current) == 2)//rebalancing { if (this.BalanceFactor(current.Left) >= 0) @@ -294,7 +293,7 @@ public sealed class AVLTree : ICollection where T : IComparable return current; } - private AVLNode Find(T target, AVLNode current) + private AVLNode? Find(T target, AVLNode current) { if (current == null) { diff --git a/SystemExtensions.NetStandard/Collections/FibonacciHeap.cs b/SystemExtensions.NetStandard/Collections/FibonacciHeap.cs index e747c2a..49c0f59 100644 --- a/SystemExtensions.NetStandard/Collections/FibonacciHeap.cs +++ b/SystemExtensions.NetStandard/Collections/FibonacciHeap.cs @@ -8,7 +8,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { #region Fields - private FibonacciNode root; + private FibonacciNode root = default!; private int count; #endregion #region Properties @@ -53,8 +53,8 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { Value = value, Marked = false, - Child = null, - Parent = null, + Child = default!, + Parent = default!, Degree = 0 }; node.Previous = node.Next = node; @@ -68,7 +68,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable public void Merge(FibonacciHeap otherHeap) { this.root = this.Merge(this.root, otherHeap.root); - otherHeap.root = null; + otherHeap.root = default!; this.count += otherHeap.count; } /// @@ -80,7 +80,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable var currentRoot = this.root; if (currentRoot != null) { - this.root = this.RemoveMinimum(this.root); + this.root = this.RemoveMinimum(this.root)!; this.count--; return currentRoot.Value; } @@ -115,8 +115,8 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { this.count = 0; this.Remove(this.root); - this.root.Next = this.root.Previous = this.root.Parent = this.root.Child = null; - this.root = null; + this.root.Next = this.root.Previous = this.root.Parent = this.root.Child = default!; + this.root = default!; } /// /// Return the heap structure as an array. Array is not sorted other than the @@ -127,7 +127,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { if (this.count == 0) { - return null; + return default!; } var array = new T[this.count]; @@ -212,12 +212,12 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable this.Remove(current.Child); if (current.Parent != null) { - current.Parent.Child = null; + current.Parent.Child = default!; } current = current.Next; } while (current != node); - current.Next = current.Previous = current.Child = current.Parent = null; + current.Next = current.Previous = current.Child = current.Parent = default!; } } /// @@ -279,7 +279,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable do { current.Marked = false; - current.Parent = null; + current.Parent = default!; current = current.Next; } while (current != node); } @@ -288,7 +288,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable /// /// Root of the provided tree. /// - private FibonacciNode RemoveMinimum(FibonacciNode node) + private FibonacciNode? RemoveMinimum(FibonacciNode node) { this.RemoveParent(node.Child); if (node.Next == node) @@ -318,7 +318,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable break; } - trees[node.Degree] = null; + trees[node.Degree] = default!; if (node.Value.CompareTo(t.Value) < 0) { t.Previous.Next = t.Next; @@ -379,7 +379,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { if (node.Next == node) { - node.Parent.Child = null; + node.Parent.Child = default!; } else { @@ -413,13 +413,13 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable { root = this.Cut(root, node); var parent = node.Parent; - node.Parent = null; + node.Parent = default!; while (parent != null && parent.Marked) { root = this.Cut(root, parent); node = parent; parent = node.Parent; - node.Parent = null; + node.Parent = default!; } if (parent != null && parent.Parent != null) @@ -449,7 +449,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable var node = root; if (node == null) { - return null; + return default!; } do @@ -467,7 +467,7 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable node = node.Next; } while (node != root); - return null; + return default!; } IEnumerator IEnumerable.GetEnumerator() { @@ -479,11 +479,11 @@ public sealed class FibonacciHeap : IEnumerable where T : IComparable internal sealed class FibonacciNode { #region Fields - private FibonacciNode previous; - private FibonacciNode next; - private FibonacciNode child; - private FibonacciNode parent; - private T value; + private FibonacciNode previous = default!; + private FibonacciNode next = default!; + private FibonacciNode child = default!; + private FibonacciNode parent = default!; + private T value = default!; private int degree; private bool marked; #endregion diff --git a/SystemExtensions.NetStandard/Collections/SkipList.cs b/SystemExtensions.NetStandard/Collections/SkipList.cs index 13a35b0..471f1f8 100644 --- a/SystemExtensions.NetStandard/Collections/SkipList.cs +++ b/SystemExtensions.NetStandard/Collections/SkipList.cs @@ -48,7 +48,7 @@ public sealed class SkipList : ICollection where T : IComparable { this.maxLevel = maxLevel; this.random = new Random(); - this.head = new NodeSet(default, maxLevel); + this.head = new NodeSet(default!, maxLevel); this.end = this.head; for (var i = 0; i <= maxLevel; i++) { @@ -242,7 +242,7 @@ public sealed class SkipList : ICollection where T : IComparable return curNode; } - return null; + return default!; } #endregion } diff --git a/SystemExtensions.NetStandard/Collections/Treap.cs b/SystemExtensions.NetStandard/Collections/Treap.cs index 49323c0..538059f 100644 --- a/SystemExtensions.NetStandard/Collections/Treap.cs +++ b/SystemExtensions.NetStandard/Collections/Treap.cs @@ -13,7 +13,7 @@ public sealed class Treap : ICollection where T : IComparable { public TKey Key; public int Priority; - public Node Left, Right; + public Node? Left, Right; public Node(TKey key, int priority) { this.Key = key; @@ -23,7 +23,7 @@ public sealed class Treap : ICollection where T : IComparable } } private readonly Random randomGen; - private Node root; + private Node root = default!; private int count; #endregion #region Properties @@ -77,7 +77,7 @@ public sealed class Treap : ICollection where T : IComparable public void Clear() { this.Clear(this.root); - this.root = null; + this.root = default!; this.count = 0; } /// @@ -93,7 +93,7 @@ public sealed class Treap : ICollection where T : IComparable /// Returns the treap structure as an ordered array. /// /// Ordered array containing the values stored in the treap. - public T[] ToArray() + public T[]? ToArray() { if (this.root != null) { @@ -104,7 +104,7 @@ public sealed class Treap : ICollection where T : IComparable } else { - return null; + return default!; } } /// @@ -135,16 +135,16 @@ public sealed class Treap : ICollection where T : IComparable } else if (key.CompareTo(node.Key) <= 0) { - node.Left = this.InsertNode(node.Left, key); - if (node.Left.Priority > node.Priority) + node.Left = this.InsertNode(node.Left!, key); + if (node.Left!.Priority > node.Priority) { node = this.RotateRight(node); } } else { - node.Right = this.InsertNode(node.Right, key); - if (node.Right.Priority > node.Priority) + node.Right = this.InsertNode(node.Right!, key); + if (node.Right!.Priority > node.Priority) { node = this.RotateLeft(node); } @@ -156,20 +156,20 @@ public sealed class Treap : ICollection where T : IComparable { if (node == null) { - return node; + return node!; } if (key.CompareTo(node.Key) < 0) { - node.Left = this.RemoveNode(node.Left, key); + node.Left = this.RemoveNode(node.Left!, key); } else if (key.CompareTo(node.Key) > 0) { - node.Right = this.RemoveNode(node.Right, key); + node.Right = this.RemoveNode(node.Right!, key); } else if (node.Left == null) { - node = node.Right; + node = node.Right!; } else if (node.Right == null) { @@ -178,26 +178,26 @@ public sealed class Treap : ICollection where T : IComparable else if (node.Left.Priority < node.Right.Priority) { node = this.RotateLeft(node); - node.Left = this.RemoveNode(node.Left, key); + node.Left = this.RemoveNode(node.Left!, key); } else { node = this.RotateRight(node); - node.Right = this.RemoveNode(node.Right, key); + node.Right = this.RemoveNode(node.Right!, key); } return node; } private Node RotateRight(Node node) { - Node temp = node.Left, temp2 = temp.Right; + Node temp = node.Left!, temp2 = temp.Right!; temp.Right = node; node.Left = temp2; return temp; } private Node RotateLeft(Node node) { - Node temp = node.Right, temp2 = temp.Left; + Node temp = node.Right!, temp2 = temp.Left!; temp.Left = node; node.Right = temp2; return temp; @@ -220,26 +220,26 @@ public sealed class Treap : ICollection where T : IComparable { if (node == null) { - return node; + return node!; } else { if (node.Key.CompareTo(key) < 0) { - var found = this.Find(node.Left, key); + var found = this.Find(node.Left!, key); if (found == null) { - found = this.Find(node.Right, key); + found = this.Find(node.Right!, key); } return found; } else if (node.Key.CompareTo(key) > 0) { - var found = this.Find(node.Right, key); + var found = this.Find(node.Right!, key); if (found == null) { - found = this.Find(node.Left, key); + found = this.Find(node.Left!, key); } return found; @@ -254,10 +254,10 @@ public sealed class Treap : ICollection where T : IComparable { if (node != null) { - this.ToArray(node.Left, ref array, ref index); + this.ToArray(node.Left!, ref array, ref index); array[index] = node.Key; index++; - this.ToArray(node.Right, ref array, ref index); + this.ToArray(node.Right!, ref array, ref index); } } private IEnumerator GetEnumerator(Node currentNode) diff --git a/SystemExtensions.NetStandard/Extensions/ObjectExtensions.cs b/SystemExtensions.NetStandard/Extensions/ObjectExtensions.cs index eda89f3..0186319 100644 --- a/SystemExtensions.NetStandard/Extensions/ObjectExtensions.cs +++ b/SystemExtensions.NetStandard/Extensions/ObjectExtensions.cs @@ -4,7 +4,7 @@ namespace System.Extensions; public static class ObjectExtensions { - public static T Deserialize(this string serialized) + public static T? Deserialize(this string serialized) where T : class { if (serialized.IsNullOrWhiteSpace()) @@ -31,7 +31,7 @@ public static class ObjectExtensions return (T)obj; } - public static T As(this object obj) where T : class + public static T? As(this object obj) where T : class { return obj as T; } diff --git a/SystemExtensions.NetStandard/Extensions/Optional.cs b/SystemExtensions.NetStandard/Extensions/Optional.cs index 4ddc170..6900288 100644 --- a/SystemExtensions.NetStandard/Extensions/Optional.cs +++ b/SystemExtensions.NetStandard/Extensions/Optional.cs @@ -7,7 +7,7 @@ public static class Optional return new Optional.None(); } - public static Optional FromValue(T value) + public static Optional FromValue(T? value) { if (value == null) { @@ -27,7 +27,7 @@ public abstract class Optional : IEquatable> private T Value { get; } - public T ExtractValue() + public T? ExtractValue() { if (this is None) { @@ -38,7 +38,7 @@ public abstract class Optional : IEquatable> return this.Value; } } - public Optional Do(Action onSome, Action onNone) + public Optional Do(Action? onSome, Action? onNone) { if (onSome is null) { @@ -61,7 +61,7 @@ public abstract class Optional : IEquatable> return this; } - public Optional DoAny(Action onSome = null, Action onNone = null) + public Optional DoAny(Action? onSome = default, Action? onNone = default) { if (this is Some) { @@ -74,7 +74,7 @@ public abstract class Optional : IEquatable> return this; } - public Optional Switch(Func onSome, Func onNone) + public Optional Switch(Func? onSome, Func? onNone) { if (onSome is null) { @@ -95,7 +95,7 @@ public abstract class Optional : IEquatable> return Optional.FromValue(onNone.Invoke()); } } - public Optional SwitchAny(Func onSome = null, Func onNone = null) + public Optional SwitchAny(Func? onSome = null, Func? onNone = null) { if (this is Some) { @@ -107,7 +107,7 @@ public abstract class Optional : IEquatable> } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is Optional) { @@ -117,17 +117,17 @@ public abstract class Optional : IEquatable> return base.Equals(obj); } - public bool Equals(Optional other) + public bool Equals(Optional? other) { if (this is Some && other is Some) { - return this.As().Equals(other.As()); + return this.As() is Some some ? some.Equals(other.As()) : false; } return false; } - public static implicit operator Optional(T value) + public static implicit operator Optional(T? value) { return Optional.FromValue(value); } @@ -143,7 +143,7 @@ public abstract class Optional : IEquatable> { } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is Some) { @@ -153,40 +153,40 @@ public abstract class Optional : IEquatable> return base.Equals(obj); } - public bool Equals(Some other) + public bool Equals(Some? other) { if (other is None) { return false; } - if (other is Some) + if (other is not null) { - return this.Value.Equals(other.Value); + return this.Value is not null && this.Value.Equals(other.Value); } return false; } - public static bool operator ==(Some left, Some right) + public static bool operator ==(Some? left, Some right) { return left?.Equals(right) == true; } - public static bool operator !=(Some left, Some right) + public static bool operator !=(Some? left, Some right) { return left?.Equals(right) != true; } public override int GetHashCode() { - return this.Value is object ? this.Value.GetHashCode() : this.As().GetHashCode(); + return this.Value is object ? this.Value.GetHashCode() : this.As() is object obj ? obj.GetHashCode() : 0; } } internal class None : Optional { - public None() : base(default) + public None() : base(default!) { } } diff --git a/SystemExtensions.NetStandard/Extensions/Result.cs b/SystemExtensions.NetStandard/Extensions/Result.cs index 90d856f..63ad0f2 100644 --- a/SystemExtensions.NetStandard/Extensions/Result.cs +++ b/SystemExtensions.NetStandard/Extensions/Result.cs @@ -2,7 +2,7 @@ public class Result { - private readonly object value; + private readonly object? value; public Result(TSuccess successValue) { @@ -13,7 +13,7 @@ public class Result this.value = failureValue; } - public bool TryExtractSuccess(out TSuccess successValue) + public bool TryExtractSuccess(out TSuccess? successValue) { if (this.value is TSuccess success) @@ -27,7 +27,7 @@ public class Result return false; } } - public bool TryExtractFailure(out TFailure failureValue) + public bool TryExtractFailure(out TFailure? failureValue) { if (this.value is TFailure failure) @@ -64,7 +64,7 @@ public class Result return this; } - public Result DoAny(Action onSuccess = null, Action onFailure = null) + public Result DoAny(Action? onSuccess = null, Action? onFailure = null) { if (this.value is TSuccess) { @@ -100,7 +100,7 @@ public class Result return this; } - public Result DoAny(Action onSuccess = null, Action onFailure = null) + public Result DoAny(Action? onSuccess = null, Action? onFailure = null) { if (this.value is TSuccess success) { @@ -136,7 +136,7 @@ public class Result throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to {typeof(T)}"); } - public T SwitchAny(Func onSuccess = null, Func onFailure = null) + public T? SwitchAny(Func? onSuccess = null, Func? onFailure = null) { if (this.value is TSuccess success) { @@ -176,11 +176,11 @@ public class Result { if (this.value is TSuccess success) { - return Result.Success(onSuccess is null ? default : onSuccess.Invoke(success)); + return Result.Success(onSuccess is not null ? onSuccess.Invoke(success) : default!); } else if (this.value is TFailure failure) { - return Result.Failure(onFailure is null ? default : onFailure.Invoke(failure)); + return Result.Failure(onFailure is not null ? onFailure.Invoke(failure) : default!); } throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to Result of type {typeof(V)} or {typeof(K)}"); diff --git a/SystemExtensions.NetStandard/Extensions/TaskExtensions.cs b/SystemExtensions.NetStandard/Extensions/TaskExtensions.cs index 954e9b2..656c711 100644 --- a/SystemExtensions.NetStandard/Extensions/TaskExtensions.cs +++ b/SystemExtensions.NetStandard/Extensions/TaskExtensions.cs @@ -82,7 +82,7 @@ public static class TaskExtensions { synch.EndMessageLoop(); } - }, null); + }, default!); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); @@ -115,16 +115,16 @@ public static class TaskExtensions { synch.EndMessageLoop(); } - }, null); + }, default!); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); - return ret; + return ret!; } private class ExclusiveSynchronizationContext : SynchronizationContext { private bool done; - public Exception InnerException { get; set; } + public Exception? InnerException { get; set; } readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false); readonly Queue> items = new Queue>(); @@ -146,14 +146,14 @@ public static class TaskExtensions public void EndMessageLoop() { - this.Post(_ => this.done = true, null); + this.Post(_ => this.done = true, default!); } public void BeginMessageLoop() { while (!this.done) { - Tuple task = null; + Tuple task = default!; lock (this.items) { if (this.items.Count > 0) diff --git a/SystemExtensions.NetStandard/Http/HttpClient.cs b/SystemExtensions.NetStandard/Http/HttpClient.cs index c366471..1308ea8 100644 --- a/SystemExtensions.NetStandard/Http/HttpClient.cs +++ b/SystemExtensions.NetStandard/Http/HttpClient.cs @@ -19,7 +19,9 @@ public sealed class HttpClient : IHttpClient, IDisposable } remove { +#pragma warning disable CS8601 // Possible null reference assignment. this.eventEmitted -= value; +#pragma warning restore CS8601 // Possible null reference assignment. } } public Uri BaseAddress { get => this.httpClient.BaseAddress; set => this.httpClient.BaseAddress = value; } @@ -27,20 +29,26 @@ public sealed class HttpClient : IHttpClient, IDisposable public long MaxResponseContentBufferSize { get => this.httpClient.MaxResponseContentBufferSize; set => this.httpClient.MaxResponseContentBufferSize = value; } public TimeSpan Timeout { get => this.httpClient.Timeout; set => this.httpClient.Timeout = value; } +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public HttpClient() +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { this.httpClient = new HttpClient(); this.scope = typeof(Tscope); } +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public HttpClient( +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. HttpMessageHandler handler) { this.httpClient = new HttpClient(handler); this.scope = typeof(Tscope); } +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public HttpClient( +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. HttpMessageHandler handler, bool disposeHandler) { diff --git a/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj b/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj index 0d1f7af..780fce8 100644 --- a/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj +++ b/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj @@ -7,10 +7,11 @@ LICENSE true System - 1.5 + 1.6 Alexandru Macocian https://github.com/AlexMacocian/SystemExtensions Extensions for the System namespace + enable diff --git a/SystemExtensions.NetStandard/Threading/PriorityThreadPool.cs b/SystemExtensions.NetStandard/Threading/PriorityThreadPool.cs index 09d29be..1b9e821 100644 --- a/SystemExtensions.NetStandard/Threading/PriorityThreadPool.cs +++ b/SystemExtensions.NetStandard/Threading/PriorityThreadPool.cs @@ -111,7 +111,7 @@ public class PriorityThreadPool : IDisposable /// private volatile List threadpool; private volatile PriorityQueue tasks; - private Thread observer; + private Thread? observer; private CancellationTokenSource observerCancellationTokenSource = new CancellationTokenSource(); private readonly object tasksLock = new object(); private struct WorkerThread @@ -307,7 +307,7 @@ public class PriorityThreadPool : IDisposable //Finally, release the lock and invoke the task. thisWorkerThread.Working = true; - QueueEntry task = null; + QueueEntry task = default!; while (!Monitor.TryEnter(this.tasksLock)) { ; @@ -451,7 +451,7 @@ public class PriorityThreadPool : IDisposable /// Find a thread with Lowest or BelowNormal priority. /// /// Thread with low priority. - private Thread FindThreadWithLowPriority() + private Thread? FindThreadWithLowPriority() { foreach (var t in this.threadpool) { @@ -461,13 +461,13 @@ public class PriorityThreadPool : IDisposable } } - return null; + return default; } /// /// Find a thread with BelowNormal or Normal priority. /// /// Thread with BelowNormal or Normal priority. - private Thread FindThreadWithAcceptablePriority() + private Thread? FindThreadWithAcceptablePriority() { foreach (var t in this.threadpool) { @@ -477,7 +477,7 @@ public class PriorityThreadPool : IDisposable } } - return null; + return default; } /// /// Downgrades the priority of a thread one level. @@ -560,9 +560,9 @@ public class PriorityThreadPool : IDisposable this.tasks.Clear(); } - this.threadpool = null; - this.tasks = null; - this.observer = null; + this.threadpool = default!; + this.tasks = default!; + this.observer = default; this.disposedValue = true; } } diff --git a/SystemExtensions.NetStandard/WebSockets/ClientWebSocket.cs b/SystemExtensions.NetStandard/WebSockets/ClientWebSocket.cs new file mode 100644 index 0000000..ab86efb --- /dev/null +++ b/SystemExtensions.NetStandard/WebSockets/ClientWebSocket.cs @@ -0,0 +1,88 @@ +using Microsoft.Extensions.Logging; +using System.Extensions; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.WebSockets; + +// TODO: Cannot properly test because ClientWebSocket is sealed +public sealed class ClientWebSocket : IClientWebSocket, IDisposable +{ + private readonly ILogger? logger; + private readonly ClientWebSocket internalWebSocket = new(); + + public ClientWebSocketOptions Options => this.internalWebSocket.Options; + + public WebSocketCloseStatus? CloseStatus => this.internalWebSocket.CloseStatus; + + public string CloseStatusDescription => this.internalWebSocket.CloseStatusDescription; + + public string SubProtocol => this.internalWebSocket.SubProtocol; + + public WebSocketState State => this.internalWebSocket.State; + + public ClientWebSocket() + { + } + + public ClientWebSocket(ILogger logger) + { + this.logger = logger.ThrowIfNull(nameof(logger)); + } + + public ClientWebSocket(ClientWebSocket clientWebSocket, ILogger logger) + { + this.internalWebSocket = clientWebSocket.ThrowIfNull(nameof(clientWebSocket)); + this.logger = logger.ThrowIfNull(nameof(logger)); + } + + public void Dispose() + { + this.internalWebSocket?.Dispose(); + } + + public void Abort() + { + this.internalWebSocket.Abort(); + } + + public Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + { + var scopedLogger = this.logger?.CreateScopedLogger(nameof(CloseAsync), string.Empty); + scopedLogger?.LogInformation($"Closing websocket. Status [{closeStatus}]. Status Description [{statusDescription}]"); + return this.internalWebSocket.CloseAsync(closeStatus, statusDescription, cancellationToken); + } + + public Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + { + var scopedLogger = this.logger?.CreateScopedLogger(nameof(CloseOutputAsync), string.Empty); + scopedLogger?.LogInformation($"Closing output. Status [{closeStatus}]. Status Description [{statusDescription}]"); + return this.internalWebSocket.CloseOutputAsync(closeStatus, statusDescription, cancellationToken); + } + + public Task ConnectAsync(Uri uri, CancellationToken cancellationToken) + { + var scopedLogger = this.logger?.CreateScopedLogger(nameof(ConnectAsync), string.Empty); + scopedLogger?.LogInformation($"Connecting to {uri}"); + return this.ConnectAsync(uri, cancellationToken); + } + + public async Task ReceiveAsync(ArraySegment buffer, CancellationToken cancellationToken) + { + var scopedLogger = this.logger?.CreateScopedLogger(nameof(ConnectAsync), string.Empty); + scopedLogger?.LogInformation($"Attempting to receive bytes"); + var result = await this.ReceiveAsync(buffer, cancellationToken); + scopedLogger?.LogInformation($"Received message [{result.MessageType}]"); + scopedLogger?.LogDebug($"Type: {result.MessageType}\nCount: {result.Count}\nEndOfMessage: {result.EndOfMessage}\nCloseStatus: {result.CloseStatus}\nCloseStatusDescription: {result.CloseStatusDescription}"); + + return result; + } + + public Task SendAsync(ArraySegment buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) + { + var scopedLogger = this.logger?.CreateScopedLogger(nameof(SendAsync), string.Empty); + scopedLogger?.LogInformation($"Sending bytes"); + scopedLogger?.LogDebug($"Type: {messageType}\nCount: {buffer.Count}\nEndOfMessage: {endOfMessage}"); + return this.SendAsync(buffer, messageType, endOfMessage, cancellationToken); + } +} diff --git a/SystemExtensions.NetStandard/WebSockets/IClientWebSocket.cs b/SystemExtensions.NetStandard/WebSockets/IClientWebSocket.cs new file mode 100644 index 0000000..59808ee --- /dev/null +++ b/SystemExtensions.NetStandard/WebSockets/IClientWebSocket.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using System.Threading; + +namespace System.Net.WebSockets; + +public interface IClientWebSocket +{ + WebSocketCloseStatus? CloseStatus { get; } + + string CloseStatusDescription { get; } + + ClientWebSocketOptions Options { get; } + + WebSocketState State { get; } + + string SubProtocol { get; } + + void Abort(); + + Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken); + + Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken); + + Task ConnectAsync(Uri uri, CancellationToken cancellationToken); + + void Dispose(); + + Task ReceiveAsync(ArraySegment buffer, CancellationToken cancellationToken); + + Task SendAsync(ArraySegment buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken); +}