Hier gibt es bereits einige Antworten, aber hier ist eine Antwort, die Unity3D berücksichtigt (die Antwort ist sehr spezifisch für Unity3D, ich würde das meiste in den meisten Zusammenhängen ganz anders machen):
Im Allgemeinen verwendet Unity3D traditionell keine Ausnahmen. Wenn Sie in Unity3D eine Ausnahme auslösen, ist dies nicht vergleichbar mit einer durchschnittlichen .NET-Anwendung. Das Programm wird nicht gestoppt. Sie können den Editor jedoch so konfigurieren, dass er pausiert. Es wird nur protokolliert. Dies kann das Spiel leicht in einen ungültigen Zustand versetzen und einen Kaskadeneffekt erzeugen, der es schwierig macht, Fehler aufzuspüren. Daher würde ich im Falle von Unity sagen, dass Add
es besonders unerwünscht ist, eine Ausnahme auslösen zu lassen.
Bei der Prüfung der Ausnahmegeschwindigkeit kommt es jedoch in einigen Fällen nicht zu einer vorzeitigen Optimierung, da Mono auf einigen Plattformen in Unity funktioniert. Tatsächlich unterstützt Unity3D unter iOS einige erweiterte Skriptoptimierungen, und deaktivierte Ausnahmen * sind ein Nebeneffekt einer davon. Dies ist wirklich zu berücksichtigen, da sich diese Optimierungen für viele Benutzer als sehr wertvoll erwiesen haben und einen realistischen Fall für die Einschränkung der Verwendung von Ausnahmen in Unity3D darstellen. (* verwaltete Ausnahmen von der Engine, nicht Ihr Code)
Ich würde sagen, dass Sie in Unity einen spezielleren Ansatz wählen möchten. Ironischerweise zeigt eine sehr heruntergestimmte Antwort zum Zeitpunkt des Schreibens dieses Artikels , wie ich so etwas speziell im Kontext von Unity3D implementieren könnte (ansonsten ist so etwas wirklich inakzeptabel und selbst in Unity ist es ziemlich inelegant).
Ein anderer Ansatz, den ich in Betracht ziehen würde, besteht darin, dem Anrufer keinen Fehler anzuzeigen, sondern die Debug.LogXX
Funktionen zu verwenden. Auf diese Weise erhalten Sie dasselbe Verhalten wie beim Auslösen einer nicht behandelten Ausnahme (aufgrund der Art und Weise, wie Unity3D sie behandelt), ohne das Risiko einzugehen, dass etwas auf der ganzen Linie in einen seltsamen Zustand versetzt wird. Überlegen Sie auch, ob dies wirklich ein Fehler ist (Ist der Versuch, dasselbe Material zweimal einzulegen, in Ihrem Fall unbedingt ein Fehler? Oder ist dies möglicherweise ein Fall, in dem dies Debug.LogWarning
zutreffender ist).
Und in Bezug auf die Verwendung von Debug.LogXX
Funktionen anstelle von Ausnahmen müssen Sie immer noch überlegen, was passiert, wenn eine Ausnahme von etwas ausgelöst wird, das einen Wert zurückgibt (wie z. B. GetMaterial). Ich tendiere dazu, dies zu erreichen, indem ich Null zusammen mit der Protokollierung des Fehlers übergebe ( wieder nur in Unity ). Ich verwende dann Nullprüfungen in meinen MonoBehaviors, um sicherzustellen, dass eine Abhängigkeit wie ein Material kein Nullwert ist, und deaktiviere das MonoBehavior, falls dies der Fall ist. Ein Beispiel für ein einfaches Verhalten, für das einige Abhängigkeiten erforderlich sind, ist etwa Folgendes:
public void Awake()
{
_inputParameters = GetComponent<VehicleInputParameters>();
_rigidbody = GetComponent<Rigidbody>();
_rigidbodyTransform = _rigidbody.transform;
_raycastStrategySelector = GetComponent<RaycastStrategySelectionBehavior>();
_trackParameters =
SceneManager.InstanceOf.CurrentSceneData.GetValue<TrackParameters>();
this.DisableIfNull(() => _rigidbody);
this.DisableIfNull(() => _raycastStrategySelector);
this.DisableIfNull(() => _inputParameters);
this.DisableIfNull(() => _trackParameters);
}
SceneData.GetValue<>
ähnelt Ihrem Beispiel darin, dass es eine Funktion in einem Wörterbuch aufruft, die eine Ausnahme auslöst. Anstatt jedoch eine Ausnahme auszulösen Debug.LogError
, wird eine Stapelablaufverfolgung wie bei einer normalen Ausnahme erstellt und null zurückgegeben. Die folgenden Überprüfungen * deaktivieren das Verhalten, anstatt zuzulassen, dass es weiterhin in einem ungültigen Zustand existiert.
* Die Schecks sehen so aus, weil ich einen kleinen Helfer verwende, der eine formatierte Nachricht druckt, wenn er das Spielobjekt deaktiviert **. Einfache Null-Checks mit if
Arbeit hier (** Die Checks des Helfers werden nur in Debug-Builds kompiliert (wie bei Asserts). Die Verwendung von Lambdas und solchen Ausdrücken in Unity kann die Leistung beeinträchtigen.)
_Materials.Add
eine Ausnahme?