我有2种派生类型:
1)AggregateCalculator
2)AdditionCalculator
上述每个派生类型都有不同的transformation logic for subvariants
,并且此过程基本上涉及两个步骤:
1)变形
2)创建和存储版本
如果步骤2中有任何错误,则从当前Left and Right Subvariant
的步骤2中删除数据。
我在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);
AdditionCalculator的DeleteStatistics方法还需要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);
}
}
因此可以从Action委托访问此左右子变量Id参数,或者周围还有其他方法吗?
答案 0 :(得分:1)
Action delegate封装了一个没有参数且不返回值的方法。这意味着没有参数可访问。
当您将其作为类型Action
的参数传递时:
() => Transform(model)
...您没有通过Action<Variant>
。也就是说,您没有传递带有Variant
类型参数的方法。
您正在传递一个Action
,它代表一个带有无参数的匿名方法。这就是()
的意思。如果有参数,它们将放在这些括号内。该匿名方法的 body 是对带有参数的方法的调用。
接收到Action
的代码不知道该方法中的内容。它只是执行它。不知道
() => Transform(model)
和
() => {} // does nothing
另一种描述方式是,通过传递类型为Action
的参数,您已经隐藏了Action
表示的方法的主体。可能是任何东西。它可能是多个语句-方法内部几乎所有内容。如果您不想想要公开Action
内部正在发生的事情,这正是您要做的。
如果您想同时使用参数和来使用该参数来调用方法,则可以通过传递两个参数来代替传递类型为Action
的参数:
Variant variant, Action<Variant> action
现在您已经有了参数(Variant
)和可以将其传递给(Action<Variant>
)的方法。您会打action(variant)
。