最快的类型比较方法?

7
下面的事件可能会在每帧被调用数百次。
public bool OnCollision(Body body1, Body body2)
{
 if(body2.Tag is Dog)
      ((Dog)body2.Tag).Bark();
}

我知道使用 "is" 会导致类型转换,然后当我想要对其进行操作时,再次进行类型转换。有没有更有效的方法来检查类型?我尝试了一个控制台应用程序,使用 "if(body2.Tag.GetType() == typeOf(Dog))",但似乎比使用 "is" 还要慢。

谢谢。

4个回答

19
 if(body2.Tag is Dog)

实际上被编译为

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

在你的代码中,你又进行了一次类型转换。更好的做法是:

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

6

我会在Body对象上创建一个叫做Collided的抽象方法:

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

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

   public void Bark() { ... }
}

然后在你的碰撞函数中,只需调用涉及到的物体上的Collision函数。
public bool OnCollision(Body body1, Body body2)
{
   body2.Collision(body2);
}

这样任何类型的物体在发生碰撞时都可以执行其需要执行的任何操作,你甚至可以优化它来跟踪已经通知彼此发生碰撞的物体,并减少必须执行的函数调用次数:

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

当然,需要进行实证测试以验证此检查是否比实际调用两次更快...

可能是这样,但人们更喜欢点赞和接受提供实际示例来解决问题的答案,而不仅仅是三个单词的回答和维基百科链接。 - joshperry
实际上这并不是完全的双重分派,我的解决方案不会因传递到Body的Collision方法中的类型而有所变化。 - joshperry
+1 我更喜欢你的做法。虽然不确定它是否更快,但更加优雅。 - Patrick Desjardins

1

这种方法是否可行或有用?

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
如何使用通用的碰撞方法?这样就不需要继承了,只需要一个接口即可。
public bool OnCollision<TA,TB>(TA a, TB b)
    where TA : ICollidable
    where TB : ICollidable {
    a.Collision(b);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接