概要
using System; using System.Reflection; public static class DelegateExt { public static int GetLength<T>( string name ) { return GetLength( typeof( T ), name ); } public static int GetLength( this Type self, string name ) { var attrs = BindingFlags.GetField | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public ; var field = self.GetField( name, attrs ); if ( field == null ) { throw new ArgumentException( $"name is invalid parameter: {name}" ); } var d = field.GetValue( null ) as Delegate; if ( d == null ) return 0; var list = d.GetInvocationList(); if ( list == null ) return 0; var length = list.Length; return length; } }
上記のような関数を定義して
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { var t = typeof( Application ); Application.focusChanged += Application_focusChanged ; Application.lowMemory += Application_lowMemory ; Application.lowMemory += Application_lowMemory ; Application.logMessageReceived += Application_logMessageReceived ; Application.logMessageReceived += Application_logMessageReceived ; Application.logMessageReceived += Application_logMessageReceived ; Application.logMessageReceivedThreaded += Application_logMessageReceived ; Application.logMessageReceivedThreaded += Application_logMessageReceived ; Application.logMessageReceivedThreaded += Application_logMessageReceived ; Application.logMessageReceivedThreaded += Application_logMessageReceived ; Application.quitting += Application_quitting ; Application.quitting += Application_quitting ; Application.quitting += Application_quitting ; Application.quitting += Application_quitting ; Application.quitting += Application_quitting ; Debug.Log( t.GetLength( "focusChanged" ) ); Debug.Log( t.GetLength( "lowMemory" ) ); Debug.Log( t.GetLength( "s_LogCallbackHandler" ) ); Debug.Log( t.GetLength( "s_LogCallbackHandlerThreaded" ) ); Debug.Log( t.GetLength( "quitting" ) ); } private void Application_focusChanged( bool obj ) { } private void Application_lowMemory() { } private void Application_logMessageReceived( string condition, string stackTrace, LogType type ) { } private void Application_quitting() { } private void OnDestroy() { Application.focusChanged -= Application_focusChanged ; Application.lowMemory -= Application_lowMemory ; Application.lowMemory -= Application_lowMemory ; Application.logMessageReceived -= Application_logMessageReceived ; Application.logMessageReceived -= Application_logMessageReceived ; Application.logMessageReceived -= Application_logMessageReceived ; Application.logMessageReceivedThreaded -= Application_logMessageReceived ; Application.logMessageReceivedThreaded -= Application_logMessageReceived ; Application.logMessageReceivedThreaded -= Application_logMessageReceived ; Application.logMessageReceivedThreaded -= Application_logMessageReceived ; Application.quitting -= Application_quitting ; Application.quitting -= Application_quitting ; Application.quitting -= Application_quitting ; Application.quitting -= Application_quitting ; Application.quitting -= Application_quitting ; } }
このようなコードを記述することで
static な event の登録数を取得できます
注意
例えば Application.logMessageReceived や Application.logMessageReceivedThreaded は
内部における名前は s_LogCallbackHandler や s_LogCallbackHandlerThreaded なので、
DelegateExt.GetLength に指定する名前を間違えないようにする必要があります
using System.Reflection; using System.Text; using UnityEngine; public class Example : MonoBehaviour { private void Awake() { var attrs = BindingFlags.GetField | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public ; var t = typeof( Application ); var fields = t.GetFields( attrs ); var sb = new StringBuilder(); foreach ( var n in fields ) { sb.AppendLine( n.Name ); } Debug.Log( sb.ToString() ); } }
内部における名前は上記のようにリフレクションを使用することで
lowMemory s_LogCallbackHandler s_LogCallbackHandlerThreaded OnAdvertisingIdentifierCallback focusChanged wantsToQuit quitting s_RegisterLogCallbackDeprecated
このように取得することができます