terça-feira, 12 de janeiro de 2010

Comentário anônimo, agora ta liberado

Eu não havia percebido que o blog não estava permitindo que fosse inserido comentários anônimos. Mas agora acredito ter resolvido.

Agora você pode descer a lenha sem precisar se identificar.

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.

segunda-feira, 4 de janeiro de 2010

O que eu faço nas férias? Estudar…

Minhas férias estão acabando, e estou aproveitando os últimos dias para estudar, pois é nerd.

Bom aqui vai alguns vídeos que eu achei interessante no site da InfoQ do Greg Young que eu recomendo.

http://www.infoq.com/presentations/greg-young-unshackle-qcon08
http://www.infoq.com/presentations/TDD-in-a-DbC-World-Greg-Young.

Brincando com delegates – Parte I

Bom primeiramente feliz ano novo.

Nesses últimos meses foi difícil manter o blog, infelizmente foi muito difícil manter o foco no trabalho, estudos e blog ao mesmo tempo.
Mas como em todo ano que se inicia costumamos traçar metas, uma das minhas é publicar conteúdo com mais regularidade.

Um recurso bem legal das novas versões do .Net é o delegate, principalmente a partir do 3.0. Abaixo vou colocar um exemplo de como utilizar o delegate do tipo Action.


//Versão 1
private void mtcDate_DateChanged(object sender, DateRangeEventArgs e)
{
DateTime date = this.mtcDate.SelectionEnd;

this.dtpInitital.Value = new DateTime(date.Year
, date.Month
, date.Day
, this.dtpInitital.Value.Hour
, this.dtpInitital.Value.Minute
, this.dtpInitital.Value.Second);

this.dtpFinal.Value = new DateTime(date.Year
, date.Month
, date.Day
, this.dtpFinal.Value.Hour
, this.dtpFinal.Value.Minute
, this.dtpFinal.Value.Second);

this.lblSelectedDate.Text = date.ToShortDateString();
}

O controle dtpInitital e dtpFinal são do mesmo tipo, perceba que eu tive que repetir o mesmo código para cada controle. Pra não ter que fazer isso, podemos criar um método para executar as alterações nessárias no valor dos controles da seguinte forma:
private void mtcDate_DateChanged(object sender, DateRangeEventArgs e)
{
DateTime date = this.mtcDate.SelectionEnd;

ChangedDate(this.dtpInitital, date);
ChangedDate(this.dtpFinal, date);

this.lblSelectedDate.Text = date.ToShortDateString();
}

private void ChangeDate(DateTimePicker control, DateTime date)
{
control.Value = new DateTime(date.Year
, date.Month
, date.Day
, control.Value.Hour
, control.Value.Minute
, control.Value.Second);
}

No exemplo acima criamos o método ChangeDate para realizar as alterações nos controles que passamos no parâmetro, mas tivemos que criar um método que será chamado sempre pelo mesmo método, agora veja a mesma solução com delegate.
private void mtcDate_DateChanged(object sender, DateRangeEventArgs e)
{
DateTime date = this.mtcDate.SelectionEnd;

Action<DateTimePicker> changedDate = null;

changedDate = delegate(DateTimePicker control)
{
control.Value = new DateTime(date.Year
, date.Month
, date.Day
, control.Value.Hour
, control.Value.Minute
, control.Value.Second);
};

changedDate(this.dtpInitital);
changedDate(this.dtpFinal);

this.lblSelectedDate.Text = date.ToShortDateString();
}

Perceba que agora colocamos o método dentro do escopo do evento, não temos a repetição de código que tivemos no primeiro controle e nem criamos um método no escopo da classe que será chamado sempre pelo memso lugar.