Small .NET optimizations

This commit is contained in:
2025-02-03 22:29:42 +01:00
parent 9270f49519
commit 980dab22f3
7 changed files with 45 additions and 36 deletions

View File

@@ -10,6 +10,22 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
/// </summary> /// </summary>
public class RtuProtocol : IModbusProtocol public class RtuProtocol : IModbusProtocol
{ {
#region Fields
private static readonly byte[] _readFunctionCodes = [
(byte)ModbusFunctionCode.ReadCoils,
(byte)ModbusFunctionCode.ReadDiscreteInputs,
(byte)ModbusFunctionCode.ReadHoldingRegisters,
(byte)ModbusFunctionCode.ReadInputRegisters];
private static readonly byte[] _writeFunctionCodes = [
(byte)ModbusFunctionCode.WriteSingleCoil,
(byte)ModbusFunctionCode.WriteSingleRegister,
(byte)ModbusFunctionCode.WriteMultipleCoils,
(byte)ModbusFunctionCode.WriteMultipleRegisters];
#endregion Fields
#region Constants #region Constants
/// <summary> /// <summary>
@@ -627,7 +643,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
// - 0x03 Read Holding Registers // - 0x03 Read Holding Registers
// - 0x04 Read Input Registers // - 0x04 Read Input Registers
// do have a "following bytes" at position 3 // do have a "following bytes" at position 3
if (new[] { 0x01, 0x02, 0x03, 0x04 }.Contains(responseBytes[1])) if (_readFunctionCodes.Contains(responseBytes[1]))
{ {
// Unit ID, Function Code, ByteCount, 2x CRC and length of ByteCount // Unit ID, Function Code, ByteCount, 2x CRC and length of ByteCount
if (responseBytes.Count < 5 + responseBytes[2]) if (responseBytes.Count < 5 + responseBytes[2])
@@ -638,7 +654,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
// - 0x06 Write Single Register // - 0x06 Write Single Register
// - 0x0F Write Multiple Coils // - 0x0F Write Multiple Coils
// - 0x10 Write Multiple Registers // - 0x10 Write Multiple Registers
if (new[] { 0x05, 0x06, 0x0F, 0x10 }.Contains(responseBytes[1])) if (_writeFunctionCodes.Contains(responseBytes[1]))
{ {
// Write Single => Unit ID, Function code, 2x Address, 2x Value, 2x CRC // Write Single => Unit ID, Function code, 2x Address, 2x Value, 2x CRC
// Write Multi => Unit ID, Function code, 2x Address, 2x QuantityWritten, 2x CRC // Write Multi => Unit ID, Function code, 2x Address, 2x QuantityWritten, 2x CRC
@@ -715,13 +731,13 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
if (isError) if (isError)
throw new ModbusException("Remote Error") { ErrorCode = (ModbusErrorCode)response[2] }; throw new ModbusException("Remote Error") { ErrorCode = (ModbusErrorCode)response[2] };
if (new[] { 0x01, 0x02, 0x03, 0x04 }.Contains(fnCode)) if (_readFunctionCodes.Contains(fnCode))
{ {
if (response.Count != 5 + response[2]) if (response.Count != 5 + response[2])
throw new ModbusException("Number of following bytes does not match."); throw new ModbusException("Number of following bytes does not match.");
} }
if (new[] { 0x05, 0x06, 0x0F, 0x10 }.Contains(fnCode)) if (_writeFunctionCodes.Contains(fnCode))
{ {
if (response.Count != 8) if (response.Count != 8)
throw new ModbusException("Number of bytes does not match."); throw new ModbusException("Number of bytes does not match.");

View File

@@ -71,7 +71,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
public DeviceIdentificationRaw DeserializeReadDeviceIdentification(IReadOnlyList<byte> response) public DeviceIdentificationRaw DeserializeReadDeviceIdentification(IReadOnlyList<byte> response)
{ {
if (!_devices.TryGetValue(response[0], out var device)) if (!_devices.TryGetValue(response[0], out var _))
throw new TimeoutException("Device not found."); throw new TimeoutException("Device not found.");
var result = new DeviceIdentificationRaw var result = new DeviceIdentificationRaw

View File

@@ -65,8 +65,12 @@ namespace AMWD.Protocols.Modbus.Tcp
get => _readTimeout; get => _readTimeout;
set set
{ {
#if NET8_0_OR_GREATER
ArgumentOutOfRangeException.ThrowIfLessThan(value, TimeSpan.Zero);
#else
if (value < TimeSpan.Zero) if (value < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(value)); throw new ArgumentOutOfRangeException(nameof(value));
#endif
_readTimeout = value; _readTimeout = value;
@@ -81,8 +85,12 @@ namespace AMWD.Protocols.Modbus.Tcp
get => _writeTimeout; get => _writeTimeout;
set set
{ {
#if NET8_0_OR_GREATER
ArgumentOutOfRangeException.ThrowIfLessThan(value, TimeSpan.Zero);
#else
if (value < TimeSpan.Zero) if (value < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(value)); throw new ArgumentOutOfRangeException(nameof(value));
#endif
_writeTimeout = value; _writeTimeout = value;
@@ -376,10 +384,9 @@ namespace AMWD.Protocols.Modbus.Tcp
try try
{ {
return Dns.GetHostAddresses(hostname) return [.. Dns.GetHostAddresses(hostname)
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6) .Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
.OrderBy(a => a.AddressFamily) // prefer IPv4 .OrderBy(a => a.AddressFamily)]; // prefer IPv4
.ToArray();
} }
catch catch
{ {

View File

@@ -1,15 +1,13 @@
using System.Net; using System.Net;
using System.Net.Sockets;
namespace AMWD.Protocols.Modbus.Tcp.Utils namespace AMWD.Protocols.Modbus.Tcp.Utils
{ {
internal class IPEndPointWrapper /// <inheritdoc cref="IPEndPoint" />
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal class IPEndPointWrapper(EndPoint endPoint)
{ {
private IPEndPoint _ipEndPoint; private readonly IPEndPoint _ipEndPoint = (IPEndPoint)endPoint;
public IPEndPointWrapper(EndPoint endPoint)
{
_ipEndPoint = (IPEndPoint)endPoint;
}
#region Properties #region Properties

View File

@@ -8,14 +8,9 @@ namespace AMWD.Protocols.Modbus.Tcp.Utils
{ {
/// <inheritdoc cref="NetworkStream" /> /// <inheritdoc cref="NetworkStream" />
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal class NetworkStreamWrapper : IDisposable internal class NetworkStreamWrapper(NetworkStream stream) : IDisposable
{ {
private readonly NetworkStream _stream; private readonly NetworkStream _stream = stream;
public NetworkStreamWrapper(NetworkStream stream)
{
_stream = stream;
}
/// <inheritdoc cref="NetworkStream.Dispose" /> /// <inheritdoc cref="NetworkStream.Dispose" />
public virtual void Dispose() public virtual void Dispose()

View File

@@ -3,14 +3,11 @@ using System.Net.Sockets;
namespace AMWD.Protocols.Modbus.Tcp.Utils namespace AMWD.Protocols.Modbus.Tcp.Utils
{ {
internal class SocketWrapper : IDisposable /// <inheritdoc cref="Socket" />
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal class SocketWrapper(Socket socket) : IDisposable
{ {
private Socket _socket; private readonly Socket _socket = socket;
public SocketWrapper(Socket socket)
{
_socket = socket;
}
/// <inheritdoc cref="Socket.DualMode" /> /// <inheritdoc cref="Socket.DualMode" />
public virtual bool DualMode public virtual bool DualMode

View File

@@ -6,22 +6,18 @@ using System.Threading.Tasks;
namespace AMWD.Protocols.Modbus.Tcp.Utils namespace AMWD.Protocols.Modbus.Tcp.Utils
{ {
/// <inheritdoc cref="TcpListener" />
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal class TcpListenerWrapper : IDisposable internal class TcpListenerWrapper(IPAddress localaddr, int port) : IDisposable
{ {
#region Fields #region Fields
private TcpListener _tcpListener; private readonly TcpListener _tcpListener = new(localaddr, port);
#endregion Fields #endregion Fields
#region Constructor #region Constructor
public TcpListenerWrapper(IPAddress localaddr, int port)
{
_tcpListener = new TcpListener(localaddr, port);
}
#endregion Constructor #endregion Constructor
#region Properties #region Properties