Me parece estranho que, um objeto além de aplicar desconto, tem que saber também que, ele faz parte de uma corrente, e que ele tem a referência de um objeto, que deve ser chamado caso ele não resolva a questão.
Solucionar o problema da seguinte forma, parece-me, que deixa o código mais simples e fácil de ler, além de que me parece não ferir os princípios SRP e Open Closed:
// Suponha que exista uma interface IDesconto com os seguintes membros:
// void Calcular()
// bool DescontoFoiCalculado
// double ValorCalculado
public double AplicarDesconto(double valor)
{
var listaDePossiveisDescontos = new List<IDesconto> {
new PrimeiroDesconto(),
new SegundoDesconto(),
new TerceiroDesconto()
}
foreach (var desconto in descontos)
{
desconto.Calcular();
if (desconto.DescontoFoiCalculado)
return desconto.ValorCalculado;
}
}
Cada classe de desconto passa a fazer uma única coisa que é calcular o desconto, se for devido. E para adicionar um novo desconto basta adicioná-lo à lista.