sexta-feira, 8 de janeiro de 2010

Brincando com delegates – Partes II

Dando continuidade com o assunto delegate hoje vou mostrar um cenário bem interessante de se aplicar o Func. Recursividade.

Vamos analisar o código abaixo:

public class Task
{
private IList<Task> _subTasks;
public Task Parent { get; set; }

public Task()
{
this._subTasks = new List<Task>();
}

public void AddSubTask(Task subTask)
{
if (subTask == null)
throw new ArgumentNullException("subTask");

if (IsMyParent(subTask))
throw new InvalidOperationException("Task cannot be my parent.");

this._subTasks.Add(subTask);
}

private bool IsMyParent(Task task)
{
if (task.Parent != null && task.Parent == this)
return true;

return IsMyParent(task._subTasks);
}

private bool IsMyParent(IList<Task> subTasks)
{
return subTasks.Any(c => c == this IsMyParent(c._subTasks));
}
}

Veja que o método IsMyParent tem uma sobrecarga para verificar se a tarefa infomada no parâmetro existe nas listas dos filhos das tarefa pai, mas perceba que o método só é criado para atender a necessidade da recursividade. Será que não tem como fazer tudo uma coisa só? Opa… claro que tem.

Agora vamos ver como criar o mesmo método mas dentro do escopo do IsMyParent.

//Versão 2
private bool IsMyParent(Task task)
{
if (task.Parent != null && task.Parent == this)
return true;

Func<IList<Task>, bool> isMyParent = null;
isMyParent = delegate(IList<Task> subTasks)
{
return subTasks.Any(c => c == this isMyParent(c._subTasks));
};

return isMyParent(task._subTasks);
}


Agora a verificação na lista de sub tarefas faz parte do escopo do método.

Por se tratar de um método recursivo temos que definir um valor para o delegate antes de implementá-lo, é por essa razão que temos a declaração e a implementação do isMyParent separadas.

Nenhum comentário: