Ok, preciso de algum mestre .Net para me dizer por que a exceção no código a seguir só é lançada quando o valor de retorno é enumerado.
public IEnumerable<string> BuildFor(Environment environment)
{
if (environment == Environment.None)
{
throw new Exception($"Impossible to build for environment '{environment}'.");
}
string clientId = ClientIds.Api[environment];
foreach (string scope in scopes)
{
yield return $"api://{clientId}/{scope}";
}
}
Ok, correção: preciso de confirmação do que está acontecendo. A evidência está me dizendo que toda a chamada do método está sendo adiada, e isso é, provavelmente, uma otimização do compilador.
A pergunta seguinte: Como posso dizer ao compilador para parar de fazer isso?
Se você não quiser uma avaliação preguiçosa, basta escrever o método da maneira "tradicional", ou seja
Ou você pode garantir que a avaliação ocorra no local assim:
O compilador não tem nada a ver com isso.
Uma opção seria tornar o iterador real um método privado chamado de dentro do método que lança a exceção. O código a seguir é muito parecido com o seu e não lançará uma exceção até entrar no segundo
foreach
loop doMain
método:Esta variação funciona da mesma maneira no que diz respeito à iteração, mas será lançada na segunda
GetItems
chamada sem esperar pela enumeração:Conforme sugerido nos comentários, se a sua versão do C# suportar, você poderá usar um método local em vez de um método de membro privado. Basicamente, é apenas mover o método privado para dentro do método público e remover o
private static
. Isso fornece a mesma funcionalidade, mas evita que esse método extra seja acessado em qualquer outro lugar, de modo que o método público ainda seja independente, como era originalmente.