diff --git a/CryptoExchange.Net/Attributes/NullableAttributes.cs b/CryptoExchange.Net/Attributes/NullableAttributes.cs index 11267ea..156ac83 100644 --- a/CryptoExchange.Net/Attributes/NullableAttributes.cs +++ b/CryptoExchange.Net/Attributes/NullableAttributes.cs @@ -1,4 +1,4 @@ -#if !NETSTANDARD2_1 +#if NETSTANDARD2_0 namespace System.Diagnostics.CodeAnalysis { using System; diff --git a/CryptoExchange.Net/Caching/MemoryCache.cs b/CryptoExchange.Net/Caching/MemoryCache.cs index 35f93c2..143e07d 100644 --- a/CryptoExchange.Net/Caching/MemoryCache.cs +++ b/CryptoExchange.Net/Caching/MemoryCache.cs @@ -26,7 +26,7 @@ namespace CryptoExchange.Net.Caching /// Cached value if it was in cache public object? Get(string key, TimeSpan maxAge) { - _cache.TryGetValue(key, out CacheItem value); + _cache.TryGetValue(key, out CacheItem? value); if (value == null) return null; diff --git a/CryptoExchange.Net/Clients/BaseClient.cs b/CryptoExchange.Net/Clients/BaseClient.cs index d0740c6..0916c31 100644 --- a/CryptoExchange.Net/Clients/BaseClient.cs +++ b/CryptoExchange.Net/Clients/BaseClient.cs @@ -15,7 +15,7 @@ namespace CryptoExchange.Net.Clients /// /// Version of the CryptoExchange.Net base library /// - public Version CryptoExchangeLibVersion { get; } = typeof(BaseClient).Assembly.GetName().Version; + public Version CryptoExchangeLibVersion { get; } = typeof(BaseClient).Assembly.GetName().Version!; /// /// Version of the client implementation @@ -27,7 +27,7 @@ namespace CryptoExchange.Net.Clients lock(_versionLock) { if (_exchangeVersion == null) - _exchangeVersion = GetType().Assembly.GetName().Version; + _exchangeVersion = GetType().Assembly.GetName().Version!; return _exchangeVersion; } diff --git a/CryptoExchange.Net/Clients/RestApiClient.cs b/CryptoExchange.Net/Clients/RestApiClient.cs index 91e999a..ace6642 100644 --- a/CryptoExchange.Net/Clients/RestApiClient.cs +++ b/CryptoExchange.Net/Clients/RestApiClient.cs @@ -807,7 +807,7 @@ namespace CryptoExchange.Net.Clients if (parameterPosition == HttpMethodParameterPosition.InUri) { foreach (var parameter in parameters) - uri = uri.AddQueryParmeter(parameter.Key, parameter.Value.ToString()); + uri = uri.AddQueryParmeter(parameter.Key, parameter.Value.ToString()!); } var headers = new Dictionary(); diff --git a/CryptoExchange.Net/Converters/JsonNet/ArrayConverter.cs b/CryptoExchange.Net/Converters/JsonNet/ArrayConverter.cs index 6a286da..4a2180e 100644 --- a/CryptoExchange.Net/Converters/JsonNet/ArrayConverter.cs +++ b/CryptoExchange.Net/Converters/JsonNet/ArrayConverter.cs @@ -36,7 +36,7 @@ namespace CryptoExchange.Net.Converters.JsonNet var result = Activator.CreateInstance(objectType); var arr = JArray.Load(reader); - return ParseObject(arr, result, objectType); + return ParseObject(arr, result!, objectType); } private static object ParseObject(JArray arr, object result, Type objectType) @@ -58,25 +58,25 @@ namespace CryptoExchange.Net.Converters.JsonNet var count = 0; if (innerArray.Count == 0) { - var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { 0 }); + var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { 0 })!; property.SetValue(result, arrayResult); } else if (innerArray[0].Type == JTokenType.Array) { - var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { innerArray.Count }); + var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { innerArray.Count })!; foreach (var obj in innerArray) { var innerObj = Activator.CreateInstance(objType!); - arrayResult[count] = ParseObject((JArray)obj, innerObj, objType!); + arrayResult[count] = ParseObject((JArray)obj, innerObj!, objType!); count++; } property.SetValue(result, arrayResult); } else { - var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { 1 }); + var arrayResult = (IList)Activator.CreateInstance(property.PropertyType, new [] { 1 })!; var innerObj = Activator.CreateInstance(objType!); - arrayResult[0] = ParseObject(innerArray, innerObj, objType!); + arrayResult[0] = ParseObject(innerArray, innerObj!, objType!); property.SetValue(result, arrayResult); } continue; @@ -88,7 +88,7 @@ namespace CryptoExchange.Net.Converters.JsonNet object? value; if (converterAttribute != null) { - value = arr[attribute.Index].ToObject(property.PropertyType, new JsonSerializer {Converters = {(JsonConverter) Activator.CreateInstance(converterAttribute.ConverterType)}}); + value = arr[attribute.Index].ToObject(property.PropertyType, new JsonSerializer {Converters = {(JsonConverter) Activator.CreateInstance(converterAttribute.ConverterType)!}}); } else if (conversionAttribute != null) { @@ -120,7 +120,7 @@ namespace CryptoExchange.Net.Converters.JsonNet } else if ((property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal?)) - && (value != null && value.ToString().IndexOf("e", StringComparison.OrdinalIgnoreCase) >= 0)) + && (value != null && value.ToString()!.IndexOf("e", StringComparison.OrdinalIgnoreCase) >= 0)) { var v = value.ToString(); if (decimal.TryParse(v, NumberStyles.Float, CultureInfo.InvariantCulture, out var dec)) @@ -164,7 +164,7 @@ namespace CryptoExchange.Net.Converters.JsonNet last = arrayProp.Index; var converterAttribute = GetCustomAttribute(prop); if (converterAttribute != null) - writer.WriteRawValue(JsonConvert.SerializeObject(prop.GetValue(value), (JsonConverter)Activator.CreateInstance(converterAttribute.ConverterType))); + writer.WriteRawValue(JsonConvert.SerializeObject(prop.GetValue(value), (JsonConverter)Activator.CreateInstance(converterAttribute.ConverterType)!)); else if (!IsSimple(prop.PropertyType)) serializer.Serialize(writer, prop.GetValue(value)); else @@ -187,9 +187,9 @@ namespace CryptoExchange.Net.Converters.JsonNet } private static T? GetCustomAttribute(MemberInfo memberInfo) where T : Attribute => - (T?)_attributeByMemberInfoAndTypeCache.GetOrAdd((memberInfo, typeof(T)), tuple => memberInfo.GetCustomAttribute(typeof(T))); + (T?)_attributeByMemberInfoAndTypeCache.GetOrAdd((memberInfo, typeof(T)), tuple => memberInfo.GetCustomAttribute(typeof(T))!); private static T? GetCustomAttribute(Type type) where T : Attribute => - (T?)_attributeByTypeAndTypeCache.GetOrAdd((type, typeof(T)), tuple => type.GetCustomAttribute(typeof(T))); + (T?)_attributeByTypeAndTypeCache.GetOrAdd((type, typeof(T)), tuple => type.GetCustomAttribute(typeof(T))!); } } diff --git a/CryptoExchange.Net/Converters/JsonNet/BigDecimalConverter.cs b/CryptoExchange.Net/Converters/JsonNet/BigDecimalConverter.cs index ad773b1..80777c1 100644 --- a/CryptoExchange.Net/Converters/JsonNet/BigDecimalConverter.cs +++ b/CryptoExchange.Net/Converters/JsonNet/BigDecimalConverter.cs @@ -27,7 +27,7 @@ namespace CryptoExchange.Net.Converters.JsonNet { try { - return decimal.Parse(reader.Value!.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture); + return decimal.Parse(reader.Value!.ToString()!, NumberStyles.Float, CultureInfo.InvariantCulture); } catch (OverflowException) { @@ -40,7 +40,7 @@ namespace CryptoExchange.Net.Converters.JsonNet { try { - var value = reader.Value!.ToString(); + var value = reader.Value!.ToString()!; return decimal.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); } catch (OverflowException) diff --git a/CryptoExchange.Net/Converters/JsonNet/BoolConverter.cs b/CryptoExchange.Net/Converters/JsonNet/BoolConverter.cs index 4b60ee2..4f519dd 100644 --- a/CryptoExchange.Net/Converters/JsonNet/BoolConverter.cs +++ b/CryptoExchange.Net/Converters/JsonNet/BoolConverter.cs @@ -34,7 +34,7 @@ namespace CryptoExchange.Net.Converters.JsonNet /// public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { - var value = reader.Value?.ToString().ToLower().Trim(); + var value = reader.Value?.ToString()!.ToLower().Trim(); if (value == null || value == "") { if (Nullable.GetUnderlyingType(objectType) != null) diff --git a/CryptoExchange.Net/Converters/JsonNet/JsonNetMessageAccessor.cs b/CryptoExchange.Net/Converters/JsonNet/JsonNetMessageAccessor.cs index bd54ad7..2938ee4 100644 --- a/CryptoExchange.Net/Converters/JsonNet/JsonNetMessageAccessor.cs +++ b/CryptoExchange.Net/Converters/JsonNet/JsonNetMessageAccessor.cs @@ -297,7 +297,7 @@ namespace CryptoExchange.Net.Converters.JsonNet // Try getting the underlying byte[] instead of the ToArray to prevent creating a copy using var stream = MemoryMarshal.TryGetArray(data, out var arraySegment) - ? new MemoryStream(arraySegment.Array, arraySegment.Offset, arraySegment.Count) + ? new MemoryStream(arraySegment.Array!, arraySegment.Offset, arraySegment.Count) : new MemoryStream(data.ToArray()); using var reader = new StreamReader(stream, Encoding.UTF8, false, Math.Max(2, data.Length), true); using var jsonTextReader = new JsonTextReader(reader); diff --git a/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs index e310145..8d16480 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs @@ -23,7 +23,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type converterType = typeof(ArrayConverterInner<>).MakeGenericType(typeToConvert); - return (JsonConverter)Activator.CreateInstance(converterType); + return (JsonConverter)Activator.CreateInstance(converterType)!; } private class ArrayPropertyInfo @@ -79,7 +79,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson JsonSerializerOptions? typeOptions = null; if (prop.JsonConverterType != null) { - var converter = (JsonConverter)Activator.CreateInstance(prop.JsonConverterType); + var converter = (JsonConverter)Activator.CreateInstance(prop.JsonConverterType)!; typeOptions = new JsonSerializerOptions(); typeOptions.Converters.Clear(); typeOptions.Converters.Add(converter); @@ -90,7 +90,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson if (prop.PropertyInfo.PropertyType == typeof(string)) writer.WriteStringValue(Convert.ToString(objValue, CultureInfo.InvariantCulture)); else - writer.WriteRawValue(Convert.ToString(objValue, CultureInfo.InvariantCulture)); + writer.WriteRawValue(Convert.ToString(objValue, CultureInfo.InvariantCulture)!); } else { @@ -107,7 +107,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson if (reader.TokenType == JsonTokenType.Null) return default; - var result = Activator.CreateInstance(typeToConvert); + var result = Activator.CreateInstance(typeToConvert)!; return (T)ParseObject(ref reader, result, typeToConvert, options); } @@ -177,7 +177,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson { if (!_converterOptionsCache.TryGetValue(attribute.JsonConverterType, out var newOptions)) { - var converter = (JsonConverter)Activator.CreateInstance(attribute.JsonConverterType); + var converter = (JsonConverter)Activator.CreateInstance(attribute.JsonConverterType)!; newOptions = new JsonSerializerOptions { NumberHandling = SerializerOptions.WithConverters.NumberHandling, @@ -209,7 +209,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson } if (targetType.IsAssignableFrom(value?.GetType())) - attribute.PropertyInfo.SetValue(result, value == null ? null : value); + attribute.PropertyInfo.SetValue(result, value); else attribute.PropertyInfo.SetValue(result, value == null ? null : Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture)); } diff --git a/CryptoExchange.Net/Converters/SystemTextJson/BigDecimalConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/BigDecimalConverter.cs index 0a24dc1..4598f16 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/BigDecimalConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/BigDecimalConverter.cs @@ -17,7 +17,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson { try { - return decimal.Parse(reader.GetString(), NumberStyles.Float, CultureInfo.InvariantCulture); + return decimal.Parse(reader.GetString()!, NumberStyles.Float, CultureInfo.InvariantCulture); } catch(OverflowException) { diff --git a/CryptoExchange.Net/Converters/SystemTextJson/BoolConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/BoolConverter.cs index 50df293..2f45135 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/BoolConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/BoolConverter.cs @@ -21,7 +21,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type converterType = typeof(BoolConverterInner<>).MakeGenericType(typeToConvert); - return (JsonConverter)Activator.CreateInstance(converterType); + return (JsonConverter)Activator.CreateInstance(converterType)!; } private class BoolConverterInner : JsonConverter diff --git a/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs index bfb0bfb..1035e2d 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs @@ -27,7 +27,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type converterType = typeof(DateTimeConverterInner<>).MakeGenericType(typeToConvert); - return (JsonConverter)Activator.CreateInstance(converterType); + return (JsonConverter)Activator.CreateInstance(converterType)!; } private class DateTimeConverterInner : JsonConverter @@ -74,7 +74,9 @@ namespace CryptoExchange.Net.Converters.SystemTextJson public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { if (value == null) + { writer.WriteNullValue(); + } else { var dtValue = (DateTime)(object)value; diff --git a/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs b/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs index c831ea8..c58c0e3 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs @@ -24,7 +24,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson /// public override JsonConverter CreateConverter(Type typeToConvert) { - return (JsonConverter)Activator.CreateInstance(_type, _parameters); + return (JsonConverter)Activator.CreateInstance(_type, _parameters)!; } } diff --git a/CryptoExchange.Net/CryptoExchange.Net.csproj b/CryptoExchange.Net/CryptoExchange.Net.csproj index 76dc198..64929ef 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.csproj +++ b/CryptoExchange.Net/CryptoExchange.Net.csproj @@ -1,6 +1,6 @@ - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;net9.0 CryptoExchange.Net diff --git a/CryptoExchange.Net/ExtensionMethods.cs b/CryptoExchange.Net/ExtensionMethods.cs index 4c14859..363959c 100644 --- a/CryptoExchange.Net/ExtensionMethods.cs +++ b/CryptoExchange.Net/ExtensionMethods.cs @@ -67,7 +67,7 @@ namespace CryptoExchange.Net { if (serializationType == ArrayParametersSerialization.Array) { - uriString += $"{string.Join("&", ((object[])(urlEncodeValues ? Uri.EscapeDataString(arrayEntry.Value.ToString()) : arrayEntry.Value)).Select(v => $"{arrayEntry.Key}[]={string.Format(CultureInfo.InvariantCulture, "{0}", v)}"))}&"; + uriString += $"{string.Join("&", ((object[])(urlEncodeValues ? Uri.EscapeDataString(arrayEntry.Value.ToString()!) : arrayEntry.Value)).Select(v => $"{arrayEntry.Key}[]={string.Format(CultureInfo.InvariantCulture, "{0}", v)}"))}&"; } else if (serializationType == ArrayParametersSerialization.MultipleValues) { @@ -111,7 +111,7 @@ namespace CryptoExchange.Net formData.Add(kvp.Key, string.Format(CultureInfo.InvariantCulture, "{0}", kvp.Value)); } } - return formData.ToString(); + return formData.ToString()!; } /// @@ -366,7 +366,7 @@ namespace CryptoExchange.Net { using var decompressedStream = new MemoryStream(); using var dataStream = MemoryMarshal.TryGetArray(data, out var arraySegment) - ? new MemoryStream(arraySegment.Array, arraySegment.Offset, arraySegment.Count) + ? new MemoryStream(arraySegment.Array!, arraySegment.Offset, arraySegment.Count) : new MemoryStream(data.ToArray()); using var deflateStream = new GZipStream(new MemoryStream(data.ToArray()), CompressionMode.Decompress); deflateStream.CopyTo(decompressedStream); diff --git a/CryptoExchange.Net/Objects/ByteOrderComparer.cs b/CryptoExchange.Net/Objects/ByteOrderComparer.cs index 7ad3cbd..e2b694b 100644 --- a/CryptoExchange.Net/Objects/ByteOrderComparer.cs +++ b/CryptoExchange.Net/Objects/ByteOrderComparer.cs @@ -14,7 +14,7 @@ namespace CryptoExchange.Net.Objects /// /// /// - public int Compare(byte[] x, byte[] y) + public int Compare(byte[]? x, byte[]? y) { // Shortcuts: If both are null, they are the same. if (x == null && y == null) return 0; diff --git a/CryptoExchange.Net/Objects/OrderedStringComparer.cs b/CryptoExchange.Net/Objects/OrderedStringComparer.cs index 15e9b2d..9dfe067 100644 --- a/CryptoExchange.Net/Objects/OrderedStringComparer.cs +++ b/CryptoExchange.Net/Objects/OrderedStringComparer.cs @@ -13,7 +13,7 @@ namespace CryptoExchange.Net.Objects /// /// /// - public int Compare(string x, string y) + public int Compare(string? x, string? y) { // Shortcuts: If both are null, they are the same. if (x == null && y == null) return 0; diff --git a/CryptoExchange.Net/Objects/ParameterCollection.cs b/CryptoExchange.Net/Objects/ParameterCollection.cs index 71b1378..599067e 100644 --- a/CryptoExchange.Net/Objects/ParameterCollection.cs +++ b/CryptoExchange.Net/Objects/ParameterCollection.cs @@ -156,7 +156,7 @@ namespace CryptoExchange.Net.Objects /// public void AddSecondsString(string key, DateTime value) { - Add(key, DateTimeConverter.ConvertToSeconds(value).ToString()); + Add(key, DateTimeConverter.ConvertToSeconds(value).ToString()!); } /// @@ -167,7 +167,7 @@ namespace CryptoExchange.Net.Objects public void AddOptionalSecondsString(string key, DateTime? value) { if (value != null) - Add(key, DateTimeConverter.ConvertToSeconds(value).ToString()); + Add(key, DateTimeConverter.ConvertToSeconds(value).ToString()!); } /// @@ -187,7 +187,7 @@ namespace CryptoExchange.Net.Objects /// public void AddEnumAsInt(string key, T value) { - var stringVal = EnumConverter.GetString(value); + var stringVal = EnumConverter.GetString(value)!; Add(key, int.Parse(stringVal)!); } diff --git a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs index c85d707..bcd72a0 100644 --- a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs +++ b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs @@ -843,9 +843,9 @@ namespace CryptoExchange.Net.OrderBook internal class DescComparer : IComparer { - public int Compare(T x, T y) + public int Compare(T? x, T? y) { - return Comparer.Default.Compare(y, x); + return Comparer.Default.Compare(y!, x!); } } } diff --git a/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs b/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs index 385f065..810fca7 100644 --- a/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs +++ b/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs @@ -20,7 +20,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards /// /// Apply guard per connection /// - public static Func PerConnection { get; } = new Func((def, host, key) => def.ConnectionId.ToString()); + public static Func PerConnection { get; } = new Func((def, host, key) => def.ConnectionId.ToString()!); /// /// Apply guard per API key /// diff --git a/CryptoExchange.Net/Requests/Request.cs b/CryptoExchange.Net/Requests/Request.cs index b2db821..f73b0fc 100644 --- a/CryptoExchange.Net/Requests/Request.cs +++ b/CryptoExchange.Net/Requests/Request.cs @@ -48,7 +48,7 @@ namespace CryptoExchange.Net.Requests } /// - public Uri Uri => _request.RequestUri; + public Uri Uri => _request.RequestUri!; /// public int RequestId { get; } diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs index 594a4bd..bd28507 100644 --- a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs @@ -60,8 +60,8 @@ namespace CryptoExchange.Net.SharedApis } else { - if (param.Names.All(x => ExchangeParameters.HasValue(exchangeParameters, exchange, x, param.ValueType) != true)) - return new ArgumentError($"One of exchange parameters `{string.Join(", ", param.Names)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); + if (param.Names!.All(x => ExchangeParameters.HasValue(exchangeParameters, exchange, x, param.ValueType) != true)) + return new ArgumentError($"One of exchange parameters `{string.Join(", ", param.Names!)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); } } @@ -113,13 +113,13 @@ namespace CryptoExchange.Net.SharedApis { if (!string.IsNullOrEmpty(param.Name)) { - if (typeof(T).GetProperty(param.Name).GetValue(request, null) == null) + if (typeof(T).GetProperty(param.Name)!.GetValue(request, null) == null) return new ArgumentError($"Required optional parameter `{param.Name}` for exchange `{exchange}` is missing. Example: {param.ExampleValue}"); } else { - if (param.Names.All(x => typeof(T).GetProperty(param.Name).GetValue(request, null) == null)) - return new ArgumentError($"One of optional parameters `{string.Join(", ", param.Names)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); + if (param.Names!.All(x => typeof(T).GetProperty(param.Name!)!.GetValue(request, null) == null)) + return new ArgumentError($"One of optional parameters `{string.Join(", ", param.Names!)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); } } diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs index 2b59714..12e2745 100644 --- a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs @@ -64,7 +64,7 @@ namespace CryptoExchange.Net.SharedApis public override string ToString(string exchange) { var sb = new StringBuilder(base.ToString(exchange)); - sb.AppendLine($"Supported limit values: [{(SupportedLimits == null ? string.Join(", ", SupportedLimits) : $"{MinLimit}..{MaxLimit}")}]"); + sb.AppendLine($"Supported limit values: [{(SupportedLimits != null ? string.Join(", ", SupportedLimits) : $"{MinLimit}..{MaxLimit}")}]"); return sb.ToString(); } } diff --git a/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs b/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs index 7636556..8a5dc57 100644 --- a/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs +++ b/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs @@ -55,7 +55,7 @@ namespace CryptoExchange.Net.SharedApis { if (Name != null) return $"[{ValueType.Name}] {Name}: {Description} | example: {ExampleValue}"; - return $"[{ValueType.Name}] {string.Join(" / ", Names)}: {Description} | example: {ExampleValue}"; + return $"[{ValueType.Name}] {string.Join(" / ", Names!)}: {Description} | example: {ExampleValue}"; } } } diff --git a/CryptoExchange.Net/Sockets/CryptoExchangeWebSocketClient.cs b/CryptoExchange.Net/Sockets/CryptoExchangeWebSocketClient.cs index 1d364eb..2d8ef04 100644 --- a/CryptoExchange.Net/Sockets/CryptoExchangeWebSocketClient.cs +++ b/CryptoExchange.Net/Sockets/CryptoExchangeWebSocketClient.cs @@ -195,9 +195,12 @@ namespace CryptoExchange.Net.Sockets socket.Options.SetBuffer(_receiveBufferSize, _sendBufferSize); if (Parameters.Proxy != null) SetProxy(socket, Parameters.Proxy); - #if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER socket.Options.CollectHttpResponseDetails = true; - #endif +#endif +#if NET9_0_OR_GREATER + socket.Options.KeepAliveTimeout = TimeSpan.FromSeconds(10); +#endif } catch (PlatformNotSupportedException) { @@ -235,13 +238,13 @@ namespace CryptoExchange.Net.Sockets if (e is WebSocketException we) { - #if (NET6_0_OR_GREATER) +#if (NET6_0_OR_GREATER) if (_socket.HttpStatusCode == HttpStatusCode.TooManyRequests) { await (OnConnectRateLimited?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false); return new CallResult(new ServerRateLimitError(we.Message)); } - #else +#else // ClientWebSocket.HttpStatusCode is only available in .NET6+ https://learn.microsoft.com/en-us/dotnet/api/system.net.websockets.clientwebsocket.httpstatuscode?view=net-8.0 // Try to read 429 from the message instead if (we.Message.Contains("429")) @@ -249,7 +252,7 @@ namespace CryptoExchange.Net.Sockets await (OnConnectRateLimited?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false); return new CallResult(new ServerRateLimitError(we.Message)); } - #endif +#endif } return new CallResult(new CantConnectError()); @@ -604,14 +607,14 @@ namespace CryptoExchange.Net.Sockets if (_socket.State == WebSocketState.CloseReceived) { // Close received means it server initiated, we should send a confirmation and close the socket - _logger.SocketReceivedCloseMessage(Id, receiveResult.CloseStatus.ToString(), receiveResult.CloseStatusDescription); + _logger.SocketReceivedCloseMessage(Id, receiveResult.CloseStatus.ToString()!, receiveResult.CloseStatusDescription ?? string.Empty); if (_closeTask?.IsCompleted != false) _closeTask = CloseInternalAsync(); } else { // Means the socket is now closed and we were the one initiating it - _logger.SocketReceivedCloseConfirmation(Id, receiveResult.CloseStatus.ToString(), receiveResult.CloseStatusDescription); + _logger.SocketReceivedCloseConfirmation(Id, receiveResult.CloseStatus.ToString()!, receiveResult.CloseStatusDescription ?? string.Empty); } break; @@ -626,7 +629,7 @@ namespace CryptoExchange.Net.Sockets // Write the data to a memory stream to be reassembled later if (multipartStream == null) multipartStream = new MemoryStream(); - multipartStream.Write(buffer.Array, buffer.Offset, receiveResult.Count); + multipartStream.Write(buffer.Array!, buffer.Offset, receiveResult.Count); } else { @@ -640,7 +643,7 @@ namespace CryptoExchange.Net.Sockets { // Received the end of a multipart message, write to memory stream for reassembling _logger.SocketReceivedPartialMessage(Id, receiveResult.Count); - multipartStream!.Write(buffer.Array, buffer.Offset, receiveResult.Count); + multipartStream!.Write(buffer.Array!, buffer.Offset, receiveResult.Count); } break; diff --git a/CryptoExchange.Net/Sockets/SocketConnection.cs b/CryptoExchange.Net/Sockets/SocketConnection.cs index a1deaaa..e844272 100644 --- a/CryptoExchange.Net/Sockets/SocketConnection.cs +++ b/CryptoExchange.Net/Sockets/SocketConnection.cs @@ -398,7 +398,7 @@ namespace CryptoExchange.Net.Sockets /// protected virtual Task HandleRequestRateLimitedAsync(int requestId) { - Query query; + Query? query; lock (_listenersLock) { query = _listeners.OfType().FirstOrDefault(x => x.Id == requestId); @@ -427,7 +427,7 @@ namespace CryptoExchange.Net.Sockets /// Id of the request sent protected virtual Task HandleRequestSentAsync(int requestId) { - Query query; + Query? query; lock (_listenersLock) { query = _listeners.OfType().FirstOrDefault(x => x.Id == requestId); diff --git a/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs b/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs index 3c317e4..4d7b3ad 100644 --- a/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs +++ b/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs @@ -378,7 +378,7 @@ namespace CryptoExchange.Net.Testing.Comparers if (objectValue is bool boolVal && jsonValue.Value() != boolVal) throw new Exception($"{method}: {property} not equal: {jsonValue.Value()} vs {(bool)objectValue}"); - if (jsonValue.Value() != bool.Parse(objectValue.ToString())) + if (jsonValue.Value() != bool.Parse(objectValue.ToString()!)) throw new Exception($"{method}: {property} not equal: {jsonValue.Value()} vs {(bool)objectValue}"); } } diff --git a/CryptoExchange.Net/Testing/Comparers/SystemTextJsonComparer.cs b/CryptoExchange.Net/Testing/Comparers/SystemTextJsonComparer.cs index 871127a..4ee5b87 100644 --- a/CryptoExchange.Net/Testing/Comparers/SystemTextJsonComparer.cs +++ b/CryptoExchange.Net/Testing/Comparers/SystemTextJsonComparer.cs @@ -211,7 +211,7 @@ namespace CryptoExchange.Net.Testing.Comparers if (dictProp.Value.Type == JTokenType.Object) { - CheckPropertyValue(method, dictProp.Value, dict[dictProp.Name]!, dict[dictProp.Name].GetType(), null, null, ignoreProperties); + CheckPropertyValue(method, dictProp.Value, dict[dictProp.Name]!, dict[dictProp.Name]!.GetType(), null, null, ignoreProperties); } else { diff --git a/CryptoExchange.Net/Testing/EnumValueTraceListener.cs b/CryptoExchange.Net/Testing/EnumValueTraceListener.cs index ce19264..3b13193 100644 --- a/CryptoExchange.Net/Testing/EnumValueTraceListener.cs +++ b/CryptoExchange.Net/Testing/EnumValueTraceListener.cs @@ -5,8 +5,11 @@ namespace CryptoExchange.Net.Testing { internal class EnumValueTraceListener : TraceListener { - public override void Write(string message) + public override void Write(string? message) { + if (message == null) + return; + if (message.Contains("Cannot map")) throw new Exception("Enum value error: " + message); @@ -14,8 +17,11 @@ namespace CryptoExchange.Net.Testing throw new Exception("Enum null error: " + message); } - public override void WriteLine(string message) + public override void WriteLine(string? message) { + if (message == null) + return; + if (message.Contains("Cannot map")) throw new Exception("Enum value error: " + message); diff --git a/CryptoExchange.Net/Testing/TestHelpers.cs b/CryptoExchange.Net/Testing/TestHelpers.cs index 0f91d44..532dbbe 100644 --- a/CryptoExchange.Net/Testing/TestHelpers.cs +++ b/CryptoExchange.Net/Testing/TestHelpers.cs @@ -169,7 +169,7 @@ namespace CryptoExchange.Net.Testing { var assembly = Assembly.GetAssembly(clientType); var interfaceType = clientType.GetInterface("I" + clientType.Name); - var clientInterfaces = assembly.GetTypes().Where(t => t.Name.StartsWith("I" + clientType.Name) && !t.Name.EndsWith("Shared")); + var clientInterfaces = assembly!.GetTypes().Where(t => t.Name.StartsWith("I" + clientType.Name) && !t.Name.EndsWith("Shared")); foreach (var clientInterface in clientInterfaces) { @@ -179,9 +179,7 @@ namespace CryptoExchange.Net.Testing int methods = 0; foreach (var method in implementation.GetMethods().Where(m => implementationTypes.IsAssignableFrom(m.ReturnType))) { - var interfaceMethod = clientInterface.GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray()); - if (interfaceMethod == null) - throw new Exception($"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); + var interfaceMethod = clientInterface.GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray()) ?? throw new Exception($"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); methods++; }