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:
Postar um comentário