MSDN에서이 구문을 yield break
보았지만 그 기능을 모르겠습니다. 아는 사람 있나요?
MyList.Add(...)
그냥 do 와 같은 코드를 작성할 필요가 없습니다 yield return ...
. 루프를 조기에 중단하고 사용하는 가상 지원 목록을 반환해야하는 경우yield break;
MSDN에서이 구문을 yield break
보았지만 그 기능을 모르겠습니다. 아는 사람 있나요?
MyList.Add(...)
그냥 do 와 같은 코드를 작성할 필요가 없습니다 yield return ...
. 루프를 조기에 중단하고 사용하는 가상 지원 목록을 반환해야하는 경우yield break;
답변:
반복자가 끝났음을 지정합니다. 값을 리턴하지 않는 명령문 yield break
으로 생각할 수 있습니다 return
.
예를 들어, 함수를 반복자로 정의하면 함수 본문은 다음과 같습니다.
for (int i = 0; i < 5; i++)
{
yield return i;
}
Console.Out.WriteLine("You will see me");
루프가 모든 사이클을 완료하면 마지막 줄이 실행되고 콘솔 앱에 메시지가 표시됩니다.
또는 다음과 같이 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");
이 경우 마지막 명령문은 함수를 일찍 종료했기 때문에 실행되지 않습니다.
break
대신 간단 하지 않을 수 yield break
있습니까? 컴파일러는 그것에 대해 불평하지 않습니다.
break
이 경우 간단한 @orad는 루프를 중지하지만 메소드 실행을 중단하지 않으므로 마지막 행이 실행되고 "Wo n't see text"가 실제로 표시됩니다.
NullReferenceException
하면 IEnumerable의 열거자를 가져올 수 있지만 yield break는하지 않습니다 (요소가없는 인스턴스가 있음).
yield return x
경고를 사용 하면 컴파일러에서이 메소드가 Enumerator
객체 를 작성하기위한 구문 설탕이되기를 원합니다 . 이 열거 자에는 method MoveNext()
와 property가 Current
있습니다. MoveNext ()는 yield return
명령문 까지 메소드를 실행하고 해당 값을로 바꿉니다 Current
. 다음에 MoveNext를 호출하면 거기서부터 실행이 계속됩니다. yield break
Current를 null로 설정하여이 열거 자의 끝을 알리므로 a foreach (var x in myEnum())
가 끝납니다.
반복자 블록을 종료합니다 (예 : IEnumerable에 더 이상 요소가 없다고 말함).
yield
당신이 양쪽 방향으로 집합을 반복 할 수있는 키워드, 또한 당신이 아닌 행의 콜렉션의 모든 다음 요소를 취할 수
yield
. 나는 당신이 틀렸다고 말하는 것이 아니라, 당신이 제안하는 것을 봅니다. 그러나 학문적으로 .NET에는 반복자가 없으며 열거 자 (한 방향, 앞으로) 만 있습니다. stdc ++와 달리 CTS / CLR에 정의 된 "일반 반복자 프레임 워크"는 없습니다. LINQ yield return
는 콜백 메소드를 활용하는 확장 메소드와의 격차를 좁히는 데 도움이 되지만 일류 반복자가 아닌 일류 확장 메소드입니다. 결과 IEnumerable
는 발신자에게 전달하는 것 이외의 다른 방향으로 반복 될 수 없습니다.
반복자에게 끝까지 도달했음을 알려줍니다.
예로서:
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;
}
}
yield
기본적으로 IEnumerable<T>
메소드는 협력 적으로 (선점 적으로 반대로) 예약 된 스레드와 유사하게 작동합니다.
yield return
"schedule"또는 "sleep"함수를 호출하여 CPU 제어를 포기하는 스레드와 같습니다. 스레드와 IEnumerable<T>
마찬가지로이 메소드는 제어가 포기되기 전의 값과 동일한 값을 갖는 모든 로컬 변수를 사용하여 즉시 제어를 다시 얻습니다.
yield break
스레드가 기능의 끝에 도달하고 종료되는 것과 같습니다.
사람들은 "상태 머신"에 대해 이야기하지만 상태 머신은 모두 "스레드"입니다. 스레드에는 상태 (예 : 로컬 변수 값)가 있으며, 예약 될 때마다 새 상태에 도달하기 위해 몇 가지 조치를 수행합니다. 중요한 점은 yield
우리가 익숙한 운영 체제 스레드와 달리이 코드를 사용하는 코드는 반복이 수동으로 진행되거나 종료 될 때까지 시간에 고정된다는 것입니다.
반복자 블록의 전체 주제는 Jon Skeet의 책 C # in Depth 의이 무료 샘플 장 에서 잘 설명되어 있습니다.
yield break
문 정지에 열거됩니다. 실제로 yield break
추가 항목을 반환하지 않고 열거를 완료합니다.
실제로 반복자 메소드가 반복을 중지 할 수있는 두 가지 방법이 있습니다. 어떤 경우에는 메소드의 로직이 모든 항목을 반환 한 후 메소드를 자연스럽게 종료 할 수 있습니다. 예를 들면 다음과 같습니다.
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.");
}
위 예제에서 maxCount
프라임이 발견 되면 반복자 메소드는 자연스럽게 실행을 중지 합니다.
이 yield break
문은 반복자가 열거를 중단하는 또 다른 방법입니다. 열거 형을 일찍 벗어나는 방법입니다. 위와 같은 방법이 있습니다. 이번에는 메소드가 실행할 수있는 시간에 제한이 있습니다.
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.");
}
에 대한 호출을 확인하십시오 yield break
. 실제로 열거 형이 일찍 종료됩니다.
또한 yield break
작품은 평범한 것과 다르게 작동합니다 break
. 위의 예 yield break
에서를 호출하지 않고 메소드를 종료합니다 Debug.WriteLine(..)
.
여기에 http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ 가 아주 좋은 예입니다.
공용 정적 IEnumerable <int> 범위 (int min, int max) { 동안 (true) { if (min> = max) { 항복 중단; } 수율 반환 min ++; } }
설명 yield break
은 메소드 내 에서 명령문이 적중 되면 해당 메소드의 실행이 리턴없이 중지된다고 설명합니다. 결과를 제공하지 않으려는 경우가 있습니다. 항복 중단을 사용할 수 있습니다.
"수율이 실제로 무엇을 하는가"가 의미하는 바는 "어떻게 작동 하는가"입니다. 자세한 내용은 Raymond Chen의 블로그를 참조하십시오. https://devblogs.microsoft.com/oldnewthing/20080812-00/?p=21273
C # 반복자는 매우 복잡한 코드를 생성합니다.
yield 키워드는 return 키워드와 함께 사용되어 열거 자 객체에 값을 제공합니다. yield return 은 반환 되는 값을 지정합니다. yield return statement에 도달하면 현재 위치가 저장됩니다. 다음에 이터레이터가 호출 될 때이 위치에서 실행이 다시 시작됩니다.
예를 사용하여 의미를 설명하려면 :
public IEnumerable<int> SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; }
이것이 반복 될 때 리턴되는 값은 0, 2, 5입니다.
이 예제에서 카운터 변수는 로컬 변수라는 점에 유의해야 합니다. 값 2를 리턴하는 두 번째 반복 후에 세 번째 반복은 이전에 있던 위치에서 시작하며 counter 라는 로컬 변수의 이전 값 은 2입니다.
yield break
않습니다
yield return
실제로 여러 값 반환을 지원 하지 않는다고 생각 합니다. 어쩌면 그것은 당신이 실제로 의미하는 것이 아니지만, 내가 그것을 읽는 방법입니다.
yield break
것과 같은 언어 수준 열거자를 포함하지 않기 때문 입니다. 이 예제는 언롤 된 루프처럼 보입니다. 실제 코드에서는이 코드를 거의 보지 못할 것입니다 (우리는 모두 엣지 케이스를 생각할 수 있습니다). 여기에는 "반복자"가 없습니다. "반복자 블록"은 언어 사양에 따라 메소드를 넘어 확장 할 수 없습니다. 실제로 반환되는 것은 "열거 가능"입니다. stackoverflow.com/questions/742497/…foreach
yield break