Eu já vi essa sintaxe no MSDN:, yield breakmas não sei o que faz. Alguém sabe?
MyList.Add(...)apenas fazer yield return .... Se você precisa sair do loop prematuramente e retornar a lista de apoio virtual que você usaryield break;
Eu já vi essa sintaxe no MSDN:, yield breakmas não sei o que faz. Alguém sabe?
MyList.Add(...)apenas fazer yield return .... Se você precisa sair do loop prematuramente e retornar a lista de apoio virtual que você usaryield break;
Respostas:
Ele especifica que um iterador chegou ao fim. Você pode pensar yield breakem uma returndeclaração que não retorna um valor.
Por exemplo, se você definir uma função como um iterador, o corpo da função poderá ser assim:
for (int i = 0; i < 5; i++)
{
yield return i;
}
Console.Out.WriteLine("You will see me");
Observe que após o loop concluir todos os seus ciclos, a última linha é executada e você verá a mensagem no aplicativo do console.
Ou assim com yield break:
int i = 0;
while (true)
{
if (i < 5)
{
yield return i;
}
else
{
// note that i++ will not be executed after this
yield break;
}
i++;
}
Console.Out.WriteLine("Won't see me");
Nesse caso, a última instrução nunca é executada porque deixamos a função mais cedo.
breakvez de yield breakno seu exemplo acima? O compilador não se queixa disso.
breakneste caso interromperia o loop, mas não abortaria a execução do método, assim a última linha seria executada e o "Won't see me text" seria realmente visto.
NullReferenceExceptionobter o enumerador de IEnumerable, enquanto que com a quebra de rendimento, não o fará (há uma instância sem elementos).
yield return xalertas no compilador, você deseja que esse método seja um açúcar sintático para a criação de um Enumeratorobjeto. Este enumerador tem método MoveNext()e propriedade Current. MoveNext () executa o método até uma yield returninstrução e transforma esse valor em Current. Na próxima vez que MoveNext for chamado, a execução continuará a partir daí. yield breakdefine Current como null, sinalizando o final desse enumerador, para que umforeach (var x in myEnum()) termine.
Termina um bloco iterador (por exemplo, diz que não há mais elementos no IEnumerable).
yieldpalavra-chave que você pode iterar coleção em ambas as direções, além disso você pode tomar cada elemento seguinte da coleção não em uma fileira
yieldfazê-lo. não estou dizendo que você está errado, entendo o que você está sugerindo; mas academicamente não há iteradores no .NET, apenas enumeradores (uma direção, encaminhamento) - diferentemente do stdc ++, não há uma "estrutura genérica de iterador" definida no CTS / CLR. O LINQ ajuda a fechar a lacuna com métodos de extensão que utilizam yield return e também métodos de retorno de chamada , mas são métodos de extensão de primeira classe, não iteradores de primeira classe. o resultado IEnumerablenão pode, por si só, repetir em outra direção que não seja o redirecionamento do chamador.
Diz ao iterador que chegou ao fim.
Como um exemplo:
public interface INode
{
IEnumerable<Node> GetChildren();
}
public class NodeWithTenChildren : INode
{
private Node[] m_children = new Node[10];
public IEnumerable<Node> GetChildren()
{
for( int n = 0; n < 10; ++n )
{
yield return m_children[ n ];
}
}
}
public class NodeWithNoChildren : INode
{
public IEnumerable<Node> GetChildren()
{
yield break;
}
}
yieldbasicamente faz com que um IEnumerable<T>método se comporte de maneira semelhante a um encadeamento agendado cooperativamente (em oposição a preventivamente).
yield returné como um thread que chama uma função "agendamento" ou "suspensão" para abrir mão do controle da CPU. Assim como um encadeamento, o IEnumerable<T>método recupera os controles no ponto imediatamente depois, com todas as variáveis locais tendo os mesmos valores que tinham antes do controle ser liberado.
yield break é como um thread que chega ao fim de sua função e termina.
As pessoas falam sobre uma "máquina de estado", mas uma máquina de estado é tudo um "fio" realmente é. Um encadeamento possui algum estado (ou seja, valores de variáveis locais) e, toda vez que é agendado, ele executa algumas ações para alcançar um novo estado. O ponto principal yieldé que, diferentemente dos threads do sistema operacional a que estamos acostumados, o código que o utiliza é congelado no tempo até que a iteração seja avançada ou finalizada manualmente.
Todo o assunto dos blocos iteradores é abordado bem neste capítulo de amostra grátis do livro C # in Depth de Jon Skeet .
A yield breakinstrução faz com que a enumeração pare. Com efeito, yield breakconclui a enumeração sem retornar nenhum item adicional.
Considere que, na verdade, existem duas maneiras pelas quais um método iterador pode parar de iterar. Em um caso, a lógica do método poderia naturalmente sair do método depois de retornar todos os itens. Aqui está um exemplo:
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount)
{
for (var i = 0UL; i < maxCount; i++)
{
startAt = NextPrime(startAt);
yield return startAt;
}
Debug.WriteLine("All the primes were found.");
}
No exemplo acima, o método do iterador interromperá naturalmente a execução após a localização dos maxCountprimos.
A yield breakdeclaração é outra maneira de o iterador parar de enumerar. É uma maneira de interromper a enumeração mais cedo. Aqui está o mesmo método acima. Desta vez, o método tem um limite para a quantidade de tempo que o método pode executar.
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount, int maxMinutes)
{
var sw = System.Diagnostics.Stopwatch.StartNew();
for (var i = 0UL; i < maxCount; i++)
{
startAt = NextPrime(startAt);
yield return startAt;
if (sw.Elapsed.TotalMinutes > maxMinutes)
yield break;
}
Debug.WriteLine("All the primes were found.");
}
Observe a chamada para yield break. Com efeito, está saindo da enumeração mais cedo.
Observe também que o yield breaktrabalho funciona de maneira diferente do que apenas uma planície break. No exemplo acima, yield breaksai do método sem fazer a chamada para Debug.WriteLine(..).
Aqui http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ é um exemplo muito bom:
público estático IEnumerable <int> Range (int min, int max)
{
enquanto (verdadeiro)
{
if (min> = max)
{
quebra de rendimento;
}
retorno de rendimento min ++;
}
}
e explicação, que se uma yield breakinstrução for atingida em um método, a execução desse método será interrompida sem retorno. Existem algumas situações em que, quando você não deseja dar nenhum resultado, pode usar a quebra de rendimento.
quebra de rendimento é apenas uma maneira de dizer retorno pela última vez e não retornar nenhum valor
por exemplo
// returns 1,2,3,4,5
IEnumerable<int> CountToFive()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
yield break;
yield return 6;
yield return 7;
yield return 8;
yield return 9;
}
Se o que você quer dizer com "o que realmente produz quebra", é "como funciona" - consulte o blog de Raymond Chen para obter detalhes https://devblogs.microsoft.com/oldnewthing/20080812-00/?p=21273
Os iteradores C # geram código muito complicado.
A palavra-chave yield é usada junto com a palavra-chave return para fornecer um valor ao objeto enumerador. retorno de rendimento especifica o valor ou valores retornados. Quando a declaração de retorno de rendimento é alcançada, o local atual é armazenado. A execução é reiniciada nesse local na próxima vez que o iterador for chamado.
Para explicar o significado usando um exemplo:
public IEnumerable<int> SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; }
Os valores retornados quando iterados são: 0, 2, 5.
É importante observar que a variável de contador neste exemplo é uma variável local. Após a segunda iteração que retorna o valor 2, a terceira iteração começa de onde saiu antes, preservando o valor anterior da variável local denominada counter, que era 2.
yield breakfaz
yield returnrealmente suporta o retorno de vários valores. Talvez não seja isso que você realmente quis dizer, mas é assim que eu li.
yield breaké que ele não contém um enumerador no nível do idioma como a foreach- ao usar um enumerador, o yield breakvalor real é fornecido. este exemplo parece um loop desenrolado. você quase nunca verá esse código no mundo real (todos nós podemos pensar em alguns casos extremos, com certeza) também, não há "iterador" aqui. o "bloco iterador" não pode se estender além do método como uma questão de especificação de linguagem. o que realmente está sendo retornado é um "enumerável", consulte também: stackoverflow.com/questions/742497/…