Last active
June 7, 2016 00:30
-
-
Save birdinforest/c5d72df4dbed10540b331106b387cc0a to your computer and use it in GitHub Desktop.
Example of IEnumerable and IEnumerator. Show what 'yiled' statement dose.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
/// <summary> | |
/// Try to learn IEnumerable and IEnumerator. | |
/// Find out what 'yiled' statement dose. Ref: https://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx | |
/// </summary> | |
namespace Lab.IEnumerableTest { | |
public class Car | |
{ | |
public string name; | |
public int speed; | |
public string inGarageName; | |
public Car(string n, int s, string inGarageName) { name = n; speed = s; this.inGarageName = inGarageName; } | |
public string Print() { | |
return name + " " + speed + ". in garage: " + inGarageName; | |
} | |
} | |
public class Garage : IEnumerable { | |
public string name; | |
// Can go to next garage from this one. | |
public Garage gotoNext; | |
public Car[] cars = new Car[4]; | |
public Garage (string name) { | |
this.name = name; | |
cars [0] = new Car ("Mazada", 100, name); | |
cars [1] = new Car ("Toyota", 200, name); | |
cars [2] = new Car ("SuperMazada", 300, name); | |
cars [3] = new Car ("SuperToyota", 400, name); | |
} | |
public void SetNextGarage(Garage gotoNext) { | |
this.gotoNext = gotoNext; | |
} | |
// Do foreach on a garage instance will loop all cars. | |
public IEnumerator GetEnumerator() { | |
return cars.GetEnumerator (); | |
} | |
public string PrintCar(Car car) { | |
return car.name + " " + car.speed + ". in garage name: " + car.inGarageName; | |
} | |
} | |
/// <summary> | |
/// Contains several garages. They are connected one by one like a single path link. | |
/// Try to use foreach to loop all garages by IEnumerable interface. | |
/// </summary> | |
public class GarageChain : IEnumerable { | |
public Garage garageA = new Garage ("A"); | |
public Garage garageB = new Garage ("B"); | |
public Garage garageC = new Garage ("C"); | |
public GarageChain () { | |
// Connect them. | |
garageA.SetNextGarage (garageB); | |
garageB.SetNextGarage (garageC); | |
garageC.SetNextGarage (null); // Don't need this line. Just make it clear. | |
} | |
// Do foreach on GarageChian instance will loop cars in all garages. | |
public IEnumerator GetEnumerator() { | |
Garage current = garageA; | |
// NOTE: If don't use 'yield' statement, following code only loop cars in first garage. | |
// 'When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. | |
// Execution is restarted from that location the next time that the iterator function is called.' | |
while (current != null) { | |
foreach (Car car in current) { | |
yield return car; | |
} | |
current = current.gotoNext; | |
} | |
// End | |
yield break; | |
} | |
} | |
/// <summary> | |
/// Test script works on Unity3D. | |
/// </summary> | |
public class CheckCars : MonoBehaviour { | |
GarageChain chain = new GarageChain(); | |
void Start() { | |
// This is internal logic. | |
Debug.Log ("- Manully Loop - "); | |
IEnumerator carEnumerator = chain.GetEnumerator (); | |
while (carEnumerator.MoveNext ()) { | |
// This is where 'foreach' performance bug happens in Unity3D. | |
// There are boxing and unboxing operations as carEnumerator.Current is object. | |
Debug.Log ("cars: " + ((Car)carEnumerator.Current).Print ()); | |
} | |
// Wrap to foreach statement. | |
Debug.Log ("- Foreach Loop - "); | |
foreach (Car c in chain) { | |
Debug.Log ("cars: " + c.Print ()); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment