Benutzer mit den meisten Antworten
YIELD - Erklärung

Frage
-
Hallo,
kann mir jemand sagen was die Vorteile hier sind?
Warum while?
// ** Wenn der State .Crawl gebe ich 0 zurück, sonst? IEnumerator CrawlState () { Debug.Log("Crawl: Enter"); while (state == State.Crawl) { yield return 0; } Debug.Log("Crawl: Exit"); NextState(); }
Ist das FREE?
UnityEngine
und wo lade ich das herunter? Wie ist Eure Erfahrung damit?
Grüße Oliver
###################
using UnityEngine; using System.Collections; public class Monster : MonoBehaviour { public enum State { Crawl, Walk, Die, } public State state; IEnumerator CrawlState () { Debug.Log("Crawl: Enter"); while (state == State.Crawl) { yield return 0; } Debug.Log("Crawl: Exit"); NextState(); } IEnumerator WalkState () { Debug.Log("Walk: Enter"); while (state == State.Walk) { yield return 0; } Debug.Log("Walk: Exit"); NextState(); } IEnumerator DieState () { Debug.Log("Die: Enter"); while (state == State.Die) { yield return 0; } Debug.Log("Die: Exit"); } void Start () { NextState(); } void NextState () { string methodName = state.ToString() + "State"; System.Reflection.MethodInfo info = GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); StartCoroutine((IEnumerator)info.Invoke(this, null)); } }
Antworten
-
Bei jedem Next des Enumerators wird mit Current das aktuelle Element geholt. Bei der Nutzung von yield wird erst in diesem Moment das Element wirklich bereitgestellt.Zum weiteren Verständnis kannst Du Dir mal die Zeitmessung in der folgenden Demo anschauen:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Collections; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { C1 c = new C1(); Stopwatch sw = new Stopwatch(); sw.Start(); c.ArbeitOhneYield(); Console.WriteLine("Arbeit ohne Yield: {0} ms", sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); c.ArbeitMitYield(); Console.WriteLine("Arbeit mit Yield: {0} ms", sw.ElapsedMilliseconds); Console.ReadKey(); } } class C1 { internal void ArbeitOhneYield() { int i = 0; foreach (var item in ColOhneYield()) { i++; if (i > 10) return; } } internal void ArbeitMitYield() { int i = 0; foreach (var item in ColMitYield()) { i++; if (i > 10) return; } } internal List<int> ColOhneYield() { List<int> l = new List<int>(); for (int i = 0; i < 100; i++) { l.Add(DoWork(i)); } return l; } internal IEnumerable ColMitYield() { for (int i = 0; i < 100; i++) { yield return DoWork(i); } } internal int DoWork(int i) { Thread.Sleep(100); return i; } } }
--
Viele Gruesse
Peter- Als Antwort markiert O. Stippe Mittwoch, 9. Mai 2012 05:58
Alle Antworten
-
Das Benutzen einer Suchmaschine führt zu: http://unity3d.com/unity/
Hallo Stefan,
zu Punkt oben --- OK.
-- Kennst Du die Library? Zu empfehlen?
Ich kann diese Funktion mehrfach anrufen, es wird jeder Wert dann zurückgegeben.
Wo ist da der Vorteil?
private string[] strings;
private int ctr = 0;
// Enumerable classes can return an enumerator
public IEnumerator<string> GetEnumerator()
{
foreach (string s in strings)
{
yield return s;
}
}
Grüße Oliver -
Ne, die Bibliothek kenne ich nicht.
Ob die Nutzung von yield einen Vorteil bietet oder nicht, ist definitiv nicht mit diesem Quellcodefragment zu beantworten.
Hallo,
sorry eine Frage noch.
Könnte man es anders beantworten? Veranschaulichen, wo der große Vorteil von yield ist?
Grüße Oliver
- Bearbeitet O. Stippe Montag, 7. Mai 2012 10:15 Format
-
yield bietet den Vorteil, auf die Bereitstellung von Gesamtmengen für Iterationen verzichten zu können. Mit yield kann man ein Enumerator-Objekt “aufbrechen”, so dass immer nur das aktuell benötigte Element bereitgestellt werden braucht.--
Viele Gruesse
Peter -
Bei jedem Next des Enumerators wird mit Current das aktuelle Element geholt. Bei der Nutzung von yield wird erst in diesem Moment das Element wirklich bereitgestellt.Zum weiteren Verständnis kannst Du Dir mal die Zeitmessung in der folgenden Demo anschauen:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Collections; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { C1 c = new C1(); Stopwatch sw = new Stopwatch(); sw.Start(); c.ArbeitOhneYield(); Console.WriteLine("Arbeit ohne Yield: {0} ms", sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); c.ArbeitMitYield(); Console.WriteLine("Arbeit mit Yield: {0} ms", sw.ElapsedMilliseconds); Console.ReadKey(); } } class C1 { internal void ArbeitOhneYield() { int i = 0; foreach (var item in ColOhneYield()) { i++; if (i > 10) return; } } internal void ArbeitMitYield() { int i = 0; foreach (var item in ColMitYield()) { i++; if (i > 10) return; } } internal List<int> ColOhneYield() { List<int> l = new List<int>(); for (int i = 0; i < 100; i++) { l.Add(DoWork(i)); } return l; } internal IEnumerable ColMitYield() { for (int i = 0; i < 100; i++) { yield return DoWork(i); } } internal int DoWork(int i) { Thread.Sleep(100); return i; } } }
--
Viele Gruesse
Peter- Als Antwort markiert O. Stippe Mittwoch, 9. Mai 2012 05:58