2008-12-18 21 views
6

Das folgende Ereignis kann möglicherweise hunderte Male ein Bild aufgerufen werden.Schnellster Typvergleich?

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

Ich verstehe, dass die Verwendung von „ist“ bewirkt, dass ein Guss gemacht werden und dann, wenn ich mit ihm etwas tun wollen, werfen sie ein zweites Mal. Gibt es eine effizientere Möglichkeit, den Typ zu überprüfen? Ich habe eine Konsolen-App versucht "if (body2.Tag.GetType() == typeOf (Dog))" aber es scheint sogar noch langsamer als mit "ist".

Danke.

Antwort

19
if(body2.Tag is Dog) 

kompiliert wird tatsächlich als

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

In Ihrem Code, sind Sie dann wieder tun die Besetzung. Besser wäre:

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

Danke Ich habe das nicht erkannt! Das ist sehr hilfreich. –

6

Ich würde nur eine abstrakte Methode auf den Körper Objekt machen kollidierte genannt:

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

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

    public void Bark() { ... } 
} 

Dann in Ihrer Kollisionsfunktion auf den betroffenen Stellen nur Kollision nennen.

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

Auf diese Weise jede Art von Körper zu tun, was es braucht, wenn eine Kollision geschieht, könnte man sogar optimiert diese Strecke zu halten, von denen Leichen von Kollisionen mit ihnen notifiziert wurden und reduziert die Anzahl der Funktion, dass Sie Anrufe haben auszuführen:

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

natürlich wäre empirische Tests durchgeführt werden müssen, um zu bestätigen, dass diese Prüfung tatsächlich schneller ist als nur zweimal den Anruf zu tun ...

+0

Nun, das mag sein, aber die Leute mögen es, zu antworten und Antworten zu geben, die tatsächliche Beispiele liefern, um ihr Problem zu lösen, als nur eine 3-Wörter-Antwort und einen Link zu Wikipedia. – joshperry

+0

Eigentlich ist das nicht genau doppelter Versand, meine Lösung unterscheidet sich nicht durch den Typ, der in die Collision-Methode des Body übergeben wird. – joshperry

+0

+1 Ich bevorzuge es, es zu tun. Kann nicht sagen, ob es schneller ist, aber es ist eleganter. –

1

würde ein Ansatz wie dies machbar oder sinnvoll sein, ?

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

Wie wäre es mit einer generischen Kollisions-Methode? Dann gibt es keine Notwendigkeit für die Vererbung. Nur eine Schnittstelle.

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