Возврат из метода переопределения из базового метода. Единство - PullRequest
0 голосов
/ 20 июня 2019

У меня есть виртуальный метод в моем базовом классе, который перезаписывается в унаследованном классе.

Я хочу иметь возможность выходить как из базового виртуального метода, так и из метода переопределения из базового виртуального метода.

Использование bool для достижения этой цели не выглядит программно правильным.В качестве bools я думал, что в основном используются для проверки чего-либо


    public virtual bool IsHit(int damage, Vector3 hitDirection){
        if (IsDead) return false;

        aiHealth -=damage;

        if (aiHealth <= 0) {
            Death();
            return false;
        }

        return true;
    }
public override bool IsHit(int damage, Vector3 hitDirection){
        if (!base.IsHit(damage, hitDirection)) return false;

        //Do stuff when enemy is hit.


        return true;
    }

Еще один способ, которым я устал, - это тоже не чистый внешний вид.

public virtual void IsHit(int damage, Vector3 hitDirection){
        if (IsDead) return;

        aiHealth -=damage;

        if (aiHealth <= 0) {
            Death();
            return false;
        }
    }
 public override void IsHit(int damage, Vector3 hitDirection){
        base.IsHit(damage, hitDirection);
        if (IsDead) return;

        //Do stuff.
    }

Но тогда мне нужно дважды вызвать чек 'IsDead'.

В идеале я хотел бы, чтобы этот метод был пустым и иметь некоторую строку кода в виртуальном вызове void, возвращать и останавливать код, выполняемый в методе переопределения.

Или знать, какой из них являетсясамый правильный путь.

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Существует более одного способа снятия шкуры с кошки, и наилучший подход зависит от многих факторов.

Вы всегда можете вызвать исключение, чтобы выйти из метода и получить пузырек исключения до соответствующей позиции. Но вы должны делать это только в случае ошибок, что, похоже, не так.

На мой взгляд, ваш второй подход может быть подходящим, и проверка флага bool (IsDead) обычно не должна оказывать заметного влияния на производительность. Это также легко понять при чтении кода.

Если вам нужен другой подход, в котором переопределяющий метод не должен проверять, вы можете разделить метод в базовом классе следующим образом:

public void IsHit(int damage, Vector3 hitDirection){
     if (IsDead) return;
     aiHealth -=damage;

     if (aiHealth <= 0) {
         Death();
         return false;
     }
     IsHitWhenNotDead(damage, hitDirection);
}

protected virtual void IsHitWhenNotDead(int damage, Vector3 hitDirection){
}

А в производном классе:

protected override void IsHitWhenNotDead(int damage, Vector3 hitDirection){
     // Do stuff
}

Обратите внимание, что оригинал IsHit больше не virtual и не может быть переопределен. Вместо этого вы переопределяете пустой метод IsHitWhenNotDead, который вызывается только при необходимости

0 голосов
/ 20 июня 2019

Разделить логику функции на отдельный защищенный виртуальный метод, который можно переопределить

Базовый класс

public void IsHit(int damage, Vector3 hitDirection){
    OnIsHit(damage, hitDirection);
}

protected virtual bool OnIsHit(int damage, Vector3 hitDirection)
    if (IsDead) return false;

    aiHealth -=damage;

    if (aiHealth <= 0) {
        Death();
        return false;
    }

    return true;
}

Производный класс

public override bool OnIsHit(int damage, Vector3 hitDirection){
    if (!base.IsHit(damage, hitDirection)) return false;

    //Do stuff when enemy is hit.


    return true;
}

Теперь ваша основная функция IsHit возвращает пустоту, как вы хотели, но внутренняя реализация возвращает bool, чтобы сообщить детям, если ей нужно выйти из кода раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...