I'm looking for a way to automatically match the signature of a method between an interface, an abstract class and a derived class. It's really painful when I change one of the comments, to manually update it 3 times, because I have to update it in the interface, the abstract class and the derived class.. Is there a VS extension or something that could help me do that automatically? Btw, I'm using ReSharper Ultimate. Not sure if it has a such extension.
public interface IBotClient
{
/// <summary>
/// Gets account balance for an asset.
/// </summary>
/// <param name="asset">The asset.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balance.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
Task<Balance> GetBalanceAsync(string asset, CancellationToken ct = default);
/// <summary>
/// Gets account balances.
/// </summary>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balances.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
Task<IList<Balance>> GetBalancesAsync(CancellationToken ct = default);
...
}
public abstract class BotClientBase : IBotClient
{
private readonly IBinanceClient _client;
private readonly IBinanceSocketClient _socketClient;
protected BotClientBase(IBinanceClient client, IBinanceSocketClient socketClient)
{
_client = client;
_socketClient = socketClient;
}
/// <summary>
/// Gets account balance for an asset.
/// </summary>
/// <param name="asset">The asset.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balance.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
public abstract Task<Balance> GetBalanceAsync(string asset, CancellationToken ct = default);
/// <summary>
/// Gets account balances.
/// </summary>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balances.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
public abstract Task<IList<Balance>> GetBalancesAsync(CancellationToken ct = default);
...
}
public class SpotBotClient : BotClientBase
{
private readonly ILogger<SpotBotClient> _logger;
private readonly IBinanceClient _client;
private readonly IBinanceSocketClient _socketClient;
public SpotBotClient(ILogger<SpotBotClient> logger, IBinanceClient client, IBinanceSocketClient socketClient) : base(client, socketClient)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_client = client;
_socketClient = socketClient;
}
/// <summary>
/// Gets account balance for an asset.
/// </summary>
/// <param name="asset">The asset.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balance.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
public override async Task<Balance> GetBalanceAsync(string asset, CancellationToken ct = default)
{
...
}
/// <summary>
/// Gets account balances.
/// </summary>
/// <param name="ct">Cancellation token.</param>
/// <returns>The account balances.</returns>
/// <exception cref="T:ElonMuskBot.Core.Exceptions.CallFailedException">If the call fails.</exception>
public override async Task<IList<Balance>> GetBalancesAsync(CancellationToken ct = default)
{
...
}
...
}