2008-12-18 12 views
6

È possibile che il seguente evento venga chiamato centinaia di volte un frame.Confronto tipo più veloce?

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

Capisco che l'uso di "è" provoca un cast da effettuare e poi quando voglio fare qualcosa con esso, gettò una seconda volta. C'è un modo più efficiente per controllare il tipo? Ho creato un'applicazione per console che cercava "if (body2.Tag.GetType() == typeOf (Dog))" ma sembra essere ancora più lento rispetto all'utilizzo di "is".

Grazie.

risposta

19
if(body2.Tag is Dog) 

è in realtà compilato come

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

Nel codice, si sta quindi facendo di nuovo il cast. Meglio sarebbe:

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

Grazie non me ne sono reso conto! Questo è molto utile. –

6

vorrei solo fare un metodo astratto sull'oggetto corpo chiamato in collisione:

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

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

    public void Bark() { ... } 
} 

Poi nella funzione di collisione basta chiamare Collision sui corpi coinvolti.

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

In questo modo qualsiasi tipo di corpo può fare tutto ciò di cui ha bisogno in caso di collisione accade, si potrebbe anche ottimizzare questo per tenere traccia di quali organismi sono state informate di collisioni con la vicenda e ridurre il numero di chiamate di funzione che si devono eseguire:

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); 
    } 
} 

Naturalmente verifica empirica avrebbe dovuto essere fatto per verificare che questo controllo è più veloce che in realtà solo facendo la chiamata due volte ...

+0

Beh, potrebbe essere, ma alla gente piace cambiare e accettare le risposte che forniscono campioni reali per risolvere il loro problema oltre a una risposta di 3 parole e un link a wikipedia. – joshperry

+0

In realtà questo non è esattamente il doppio invio, la mia soluzione non varia in base al tipo che viene passato al metodo Collision del corpo. – joshperry

+0

+1 Preferisco il tuo modo di farlo. Non so se è più veloce ma è più elegante. –

1

sarebbe un approccio come questo sia fattibile o utile ?

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

Come su un metodo collisione generico? Quindi non c'è bisogno di ereditarietà. Solo un'interfaccia

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