2008-12-18 14 views
6

El siguiente evento se puede llamar cientos de veces un fotograma.Comparación de tipos más rápidos?

public bool OnCollision(Body body1, Body body2) 
{ 
if(body2.Tag is Dog) 
     ((Dog)body2.Tag).Bark(); 
} 

entiendo que el uso de "es" provoca un reparto que se hizo y luego cuando quiero hacer algo con él, echó una segunda vez. ¿Hay una manera más eficiente de verificar el tipo? Hice una aplicación de consola que intentaba "if (body2.Tag.GetType() == typeOf (Dog))" pero parece ser aún más lenta que con "is".

Gracias.

Respuesta

19
if(body2.Tag is Dog) 

es en realidad compilado como

Dog Temp = body2.Tag as Dog; 
if (temp != null) 

En su código, que está a continuación, haciendo el reparto de nuevo. Mejor sería:

Dog dog = body2.Tag as Dog; 
if (dog != null) 
{ 
    dog.Bark(); 
} 
+0

Gracias ¡No me di cuenta de eso! Esto es muy útil. –

6

que acaba de hacer un método abstracto en el objeto Cuerpo llamada Chocó:

abstract class Body 
{ 
    abstract void Collision(Body other); 
} 

class Dog : Body 
{ 
    public override void Collision(Body other) { 
     this.Bark(); 
    } 

    public void Bark() { ... } 
} 

Luego, en su función de colisión a llamar a la colisión de los organismos implicados.

public bool OnCollision(Body body1, Body body2) 
{ 
    body2.Collision(body2); 
} 

De esta manera cualquier tipo de cuerpo puede hacer lo que se necesita cuando ocurre una colisión, incluso se podría optimizar este no perder de vista que los cuerpos han sido notificados de las colisiones entre nosostros y reducir el número de llamadas a funciones que se tienen que ejecutar:

public bool OnCollision(Body body1, Body body2) 
{ 
    // Record that these two objects have been notified of a collision 
    // then when these same objects are the only two operands in subsequent calls 
    // you can just short circuit the calls. 
    if(!AlreadyNotifiedOfCollision(body1, body2)) 
    { 
     body1.Collision(body2); 
     body2.Collision(body1); 
     NotifiedOfCollision(body1, body2); 
    } 
} 

Por supuesto comprobación empírica tendría que hacer para validar que esta comprobación es más rápido que en realidad sólo hacer la llamada dos veces ...

+0

Bueno, puede ser, pero a las personas les gusta votar y aceptar respuestas que proporcionan muestras reales para resolver su problema, que solo una respuesta de 3 palabras y un enlace a wikipedia. – joshperry

+0

En realidad, este no es exactamente el doble despacho, mi solución no varía según el tipo que se transmite al método de colisión del cuerpo. – joshperry

+0

+1 Prefiero tu forma de hacerlo. No puedo decir si es más rápido pero es más elegante. –

1

¿sería un enfoque como este ser factible o útil ?

public interface ICollidable 
{ 
    void OnCollision(); 
} 

public abstract class Body : ICollidable 
{ 
    public abstract void OnCollision(); 
} 

public class Dog : Body 
{ 
    public override void OnCollision(); 
    { 
     Bark(); 
    } 
} 

public Boolean OnCollision(ICollidable a, ICollidable b) 
{ 
    b.OnCollision(); 
} 
0

¿Qué tal un método genérico de colisión? Entonces no hay necesidad de herencia. Solo una interfaz.

public bool OnCollision<TA,TB>(TA a, TB b) 
    where TA : ICollidable 
    where TB : ICollidable { 
    a.Collision(b); 
} 
Cuestiones relacionadas