Как получить доступ к параметрам из делегата действия и передать другому методу в случае исключения? - PullRequest
1 голос
/ 14 мая 2019

У меня есть 2 производных типа:

1) AggregateCalculator

2) AdditionCalculator

Каждый из перечисленных выше производных типов имеет различные transformation logic for subvariants, и в основном есть 2 шагаучаствует в этом процессе:

1) Tranform

2) Создать и сохранить версию

Если на шаге 2 возникла ошибка, удалить данные из шагов 2 текущего Left and Right Subvariant.

Я сохранил общий код в VariantProcessor, чтобы делиться между двумя вышеупомянутыми производными типами, но теперь проблема заключается в том, что, если есть ошибка, то как передать текущий Left and Right subvariant Id to the DeleteStatistics method.

Если я возьму Left and Right Subvariant as instance field at class level, то для моего метода ниже он не понадобится:

StatisticsModel Process(List<Subvariants> subvariants);

Метод DeleteStatistics для AdditionCalculator также требует Left и Right SubvariantId для удаления статистики для шага 1.

Код:

public interface IVariantProcessor
{
    void Process(Variant model);
    StatisticsModel Process(List<Subvariants> subvariants);
}

public class Variant
{
    public int VariantId { get; set; }
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public List<Subvariants> Subvariants { get; set; }
}

public class Subvariants
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public sealed class VariantProcessor
{
    private string _myAppConnectionString { get; set; }
    private readonly Action _transform;
    private readonly Action _deleteStep1Data;

    public Variant(string _myAppConnectionString,Action transform, Action deleteStep1Data)
    {
         _myAppConnectionString = _myAppConnectionString;
        _transform = transform;
        _deleteStep1Data = deleteStep1Data;
    }

    public void Process(Variant model)
    {
        try
        {
            _transform();
             //version creation shared by both the derived types
        }
        catch (Exception) 
        {
          _deleteStep1Data();//How to pass currently executing left and right subvariants if to this method ?
        }
    }
}

public class AggregateCalculator : IVariantProcessor
{
    private string _myAppConnectionString { get; set; }

    public StatisticsModel Process(List<Subvariants> subvariants)
    {
         //other logic
        //_myAppConnectionString is not needed for this code
    }


    public void Process(Variant model)
        {
            _myAppConnectionString = ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString;
            new VariantProcessor( _myAppConnectionString,
               () => Transform(model),
               () => DeleteStep1Data(model.VariantId));
        }

    private void Transform(Variant model)
    {
         for (int counter = 0; counter < model.Subvariants.Count - 1; counter++)
            {
                var left = model.Subvariants[counter];
                var right = model.Subvariants[counter + 1];
                //some sort of transformation process between left and right
            }
    }
    private void DeleteStep1Data(int variantId,int leftSubvariantId,int rightSubvariantId)
    {
        VariantRepo.DeleteStatistics(variantId,leftSubvariantId,rightSubvariantId);
    }
}

Так что есть возможность получить доступ к этим параметрам Id левого и правого подвариантов из делегата действия или есть какой-нибудь другой способ?

1 Ответ

1 голос
/ 14 мая 2019

Делегат Действие инкапсулирует метод, который не имеет параметров и не возвращает значение.Это означает, что нет параметров для доступа.

Когда вы передаете это как аргумент типа Action:

() => Transform(model)

... вы не передаете Action<Variant>.То есть вы не передаете метод, который принимает аргумент типа Variant.

Вы передаете Action, который представляет анонимный метод с без параметров .Вот что означает ().Если бы были параметры, они были бы внутри этих скобок. тело этого анонимного метода - это вызов метода с параметром.

Код, который получает это Action, не знает, что находится в этом методе.Это просто выполняет это.Он не знает разницы между

() => Transform(model)

и

() => {} // does nothing

Еще один способ описать это, передав аргумент типа Action, вы скрыли телометод, представленный Action.Это может быть что угодно.Это может быть несколько операторов - почти все, что будет внутри метода.Это именно то, что вы сделали бы, если бы не не хотели разоблачать то, что происходило внутри Action.

Если вы хотите, чтобы оба параметра и вызывали метод с использованием этого параметра, тогда вместо передачи аргумента типа Action вы можете передать два аргумента:

Variant variant, Action<Variant> action

Теперь у вас есть параметр (Variant) и метод, которому вы можете передать его (Action<Variant>).Вы бы позвонили action(variant).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...