Intentar tener un sistema capaz de almacenar cualquier tipo de instrucciones de rendimiento.
YieldInstruction m_yield; void SetInstruction() { switch(condition) { case UseWait: m_yield = new WaitForSeconds(1f); break; case UseWaitUntil: m_yield = new WaitUntil(() => flag == true); // Cannot cast here } }
Cambiar el tipo a IEnumerator pone el problema en el primero. CustomeYieldInstruction tampoco lo está haciendo.
No puedo identificar cuál es la relación entre YieldInstruction y CustomYieldInstruction. A pesar de los nombres, uno es su propio tipo base y el último es IEnumerator.
También estoy confundido ya que los dos métodos pueden producir un método IEnumerator pero no se incluirán en él si se hace como lo intento.
public sealed class WaitForSeconds : YieldInstruction{ /* ** */ } public class YieldInstruction { } public sealed class WaitUntil : CustomYieldInstruction { /* ** */} public abstract class CustomYieldInstruction : IEnumerator { /* ** */ }
y puedo hacer:
public IEnumerator Sequence() { yield return new WaitForSeconds(1f), yield return new WaitUntil(()=> condition == true); }
Además de la respuesta de Menyus
Diría que usar un object
es demasiado sucio para mi gusto.
Pero simplemente podría crear un IEnumerator
contenedor para aquellos tipos que no lo implementan ellos mismos (como cualquier cosa basada en los tiempos internos):
private IEnumerator WaitForYieldInstruction(YieldInstruction instruction) { yield return instruction; }
y luego usar
IEnumerator m_yield; void SetInstruction() { switch(condition) { case UseWait: m_yield = WaitForYieldInstruction(new WaitForSeconds(1f)); break; case UseWaitUntil: m_yield = new WaitUntil(() => flag); break; } }
YieldInstruction
recibe tratamientos especiales del sistema interno de Unity. Si solo observa WaitUntil
, no necesita tratamientos especiales del motor interno (C / C ++), ya que solo espera un predicado C #. Por otro lado, WaitForSeconds
, WaitForEndOfFrame
ofc necesita algunos tratamientos especiales. En el primero, necesita el temporizador interno, en el último, el programador de corrutina tiene que hacer una interrupción especial justo al final del cuadro, lo que es un poco imposible con solo el lado de secuencias de comandos administradas.
¡Además no olvides que puedes ceder cualquier cosa! null tampoco implementa IEnumerator
ni string
, etc.
Cuando llama a StartCoroutine(MyCoroutine);
básicamente está registrando el método en el programador de rutinas de Unity y está implementado en C/C++.
Volviendo a tu pregunta original. Afortunadamente, en C#, todas las clases heredan de System.Object
para que puedan tener una clase base.