Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Por: Roberto Alexis Farah
Oi pessoal!
Eis a resposta do Desafio da Semana #4.
https://blogs.technet.com/latam/archive/2006/05/12/428158.aspx
PROBLEMA
O comportamento da aplicação pode parecer estranho mas ele é coerente!
Note que o bloco finally deve sempre ser executado. E, de fato, é usado principalmente para liberar recursos reservados no bloco try, independente de uma exceção ter sido lançada ou não.
Portanto, sabemos que o bloco finally deve ser sempre executado e está sendo. (há documentação no MSDN sobre isso)
Pois bem, porque o valor da variável não mudou isso não significa que há um problema no compilador C#.
Afinal, a lógica da aplicação é para retornar o valor da variável “a” dentro do bloco try sem a interferência da execução do bloco finally.
Se uma exceção fosse disparada antes do return seria mais claro ver a necessidade do finally ser executado.
Mas, você poderia perguntar: e se o valor retornado fosse o valor do bloco finally?
Se isso ocorresse seria incoerente pois seria o mesmo que usar esse bloco de código:
public static string makeStrangeStuff()
{
StrangeStuff.a = "Anomaly";
try
{
}
finally
{
StrangeStuff.a = "Greater Anomaly";
}
return StrangeStuff.a;
}
Note que no bloco de código acima temos uma lógica diferente. No código acima o return StrangeStuff.a vem depois do bloco finally, logo, é esperado que o retorno seja o conteúdo do bloco finally!
De volta ao código original, se analisarmos o metadata temos:
public static string makeStrangeStuff()
{
string CS$1$0000;
StrangeStuff.a = "Anomaly";
try
{
CS$1$0000 = StrangeStuff.a;
}
finally
{
StrangeStuff.a = "Greater Anomaly";
}
return CS$1$0000;
}
Uma variável interna é criada para produzir o resultado atual, entretanto, se você mudar o código de modo a por o return StrangeStuff.a após o finally e usar ILDasm para ver o resultado você vai notar que o código gerado não mudou:
public static string makeStrangeStuff()
{
StrangeStuff.a = "Anomaly";
try
{
}
finally
{
StrangeStuff.a = "Greater Anomaly";
}
return StrangeStuff.a;
}
Nesse caso não há necessidade do compilador criar uma variável interna, a execução é direta.
Em relação ao código original é recomendado se usar saída de métodos (o return no caso) fora do bloco try pois, como vocês viram, pontos de saída dentro do bloco try deixam o código mais difícil de entender, menos legível.
Outro exemplo para ilustrar:
static private DateTime Test()
{
try
{
return DateTime.Now; // ß Valor retornado não vai mudar após o finally.
}
finally
{
Thread.Sleep(80000);
}
}
Infelizmente essa semana não tive tempo de preparar o próximo desafio. L
Mas até semana que vem vou fazê-lo e publicá-lo.
Até lá.