以下の内容はChatGPTからの転載です 検証後、備忘録として使うといい感じです。
元の質問: Unity は AOP メソッドを使用して属性を UIEventManager.StartListening に追加し、try...catch の効果を再生します。
AI は次のように答えました。
まず、StartListening メソッドに適用される機能を定義する機能クラスを定義する必要があります。たとえば、次のようになります。
[AttributeUsage(AttributeTargets.Method)]
public class SafeCallAttribute : Attribute
{
}
この例では、メソッドにのみ適用できる SafeCallAttribute という属性クラスが定義されています。
次に、機能を適用するコードを UIEventManager クラスの StartListening メソッドに追加します。
[SafeCall]
public void StartListening(string eventName, UnityAction listener)
{
// 在这里实现方法的逻辑
}
この例では、[SafeCall] 属性が StartListening メソッドの前に追加され、このメソッドを呼び出す前にこの機能の存在をチェックするようにプログラムに指示しています。
次に、リフレクションを使用して UIEventManager クラスの SafeCallAttribute 属性を持つすべてのメソッドを取得し、それらを try...catch ステートメントでラップする UIEventManager クラスのコードに静的メソッドを実装します。
public static void SafeCall(Action action)
{
try
{
action();
}
catch (Exception ex)
{
Debug.LogError($"Exception caught: {
ex.Message}");
}
}
public static void SafeCall(object obj, MethodInfo method, params object[] args)
{
try
{
method.Invoke(obj, args);
}
catch (Exception ex)
{
Debug.LogError($"Exception caught: {
ex.Message} -- {
ex.StackTrace}");
}
}
public static void SafeCall(object obj, string methodName, params object[] args)
{
var method = obj.GetType().GetMethod(methodName);
if(method != null)
{
SafeCall(obj, method, args);
}
else
{
Debug.LogError($"Method {
methodName} not found on type {
obj.GetType().Name}");
}
}
この例では、オーバーロードされた 3 つの SafeCall メソッドが実装されています。
SafeCall(Action アクション): Action デリゲートをパラメーターとして使用して、値を返さないメソッドを実行します。
SafeCall(object obj, MethodInfo method, params object[] args): MethodInfo とパラメーターの配列をパラメーターとして使用して、任意のタイプのメソッドを実行します。
SafeCall(object obj, string methodName, params object[] args): メソッド名とパラメーターの配列をパラメーターとして使用して、オブジェクトのメソッドを実行します。
これらのメソッドの機能は、まずメソッドに SafeCallAttribute 機能があるかどうかを確認することです. ある場合は、メソッドを try...catch ステートメントでラップして実行します. 例外が発生した場合は、エラー メッセージを記録して出力します.
最後に、メソッド呼び出しの前にリフレクションを使用して SafeCall メソッドを呼び出すコード行を StartListening メソッドに追加します。
[SafeCall]
public void StartListening(string eventName, UnityAction listener)
{
SafeCall(() => {
// 在这里实现方法的逻辑
});
}
このように、StartListening メソッドでどのような例外が発生しても、try...catch ステートメントによってキャッチされ、Debug.LogError を通じてエラー メッセージが出力されます。