Skip to content

[feature request] support extension method #95

@kirsysuv

Description

@kirsysuv

I want to add some extension method such as

public static class ClassAExtension
{
        public static void test22(this ClassA self)
        {
              //
        }
}

I tried to use a fixed parameter name "self" to identify the "this" parameter in extension method.
And some other workarounds to make extension method usable.
My implementation is not well organized and tested.

It would be great if this feature is implemented.

Here is my workaroud

==========================
	public class ConsoleMethodInfo
	{
		public readonly MethodInfo method;
		public readonly Type[] parameterTypes;
		public readonly object instance;

		public readonly string command;
		public readonly string signature;
		public readonly string[] parameters;
                // specify extension method
		public readonly bool isExtensionMethod;

		public ConsoleMethodInfo( MethodInfo method, Type[] parameterTypes, object instance, string command, string signature, string[] parameters )
		{
			this.method = method;
			this.parameterTypes = parameterTypes;
			this.instance = instance;
			this.command = command;
			this.signature = signature;
			this.parameters = parameters;
			this.isExtensionMethod = false;
		}

		public ConsoleMethodInfo( MethodInfo method, Type[] parameterTypes, object instance, string command, string signature, string[] parameters, bool isExtensionMethod )
		{
                        this.method = method;
                        this.parameterTypes = parameterTypes;
                        this.instance = instance;
                        this.command = command;
                        this.signature = signature;
                        this.parameters = parameters;
                        this.isExtensionMethod = isExtensionMethod;
        }

		public bool IsValid()
		{
			if( !method.IsStatic && ( instance == null || instance.Equals( null ) ) )
				return false;

			return true;
		}
	}
=========================
        // Add a command related with a static extension method
        public static void AddCommandExtension(string command, string description, string methodName, Type extensionClassType, object instance, params string[] parameterNames)
		{
            // Get the method from the class
            MethodInfo method = extensionClassType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);
            if (method == null)
            {
                Debug.LogError(methodName + " does not exist in " + extensionClassType);
                return;
            }

            AddCommand(command, description, method, instance, parameterNames);
        }

========================= modify AddCommand method
...
			// Fetch the parameters of the class
			ParameterInfo[] parameters = method.GetParameters();
			if( parameters == null )
				parameters = new ParameterInfo[0];

			bool isExtensionMethod = false;
			if (parameters.Length>0 && parameters[0].Name == "self")
			{
                isExtensionMethod = true;
				//remove the first parameter in parameters

				//in the case of extension method, the first parameter is the instance of the class
				//remove it from the parameters list and check if there are any parameters left
				if (parameters.Length > 1)
				{
					ParameterInfo[] newParameters = new ParameterInfo[parameters.Length - 1];
					for (int i = 1; i < parameters.Length; i++)
					{
						newParameters[i - 1] = parameters[i];
                    }
					parameters = newParameters;
				}
				else
				{
					parameters = new ParameterInfo[0];
				}
						
            }

			// Store the parameter types in an array
			Type[] parameterTypes = new Type[parameters.Length];
...

			methods.Insert( commandIndex, new ConsoleMethodInfo( method, parameterTypes, instance, command, methodSignature.ToString(), parameterSignatures, isExtensionMethod ) );

========================= modify ExecuteCommand method
...

...
			if( methodToExecute == null )
				Debug.LogWarning( !string.IsNullOrEmpty( errorMessage ) ? errorMessage : "ERROR: something went wrong" );
			else
			{
				object result;
				// Execute the method associated with the command
				if( methodToExecute.isExtensionMethod )
				{
					// If the method is an extension method, the first parameter should be the instance
					object[] newParameters = new object[parameters.Length + 1];
                                        // use instance as first parameter
					newParameters[0] = methodToExecute.instance;
                    Array.Copy( parameters, 0, newParameters, 1, parameters.Length );
                    parameters = newParameters;
                    result = methodToExecute.method.Invoke(null, parameters);
				}
                else
				{
					result = methodToExecute.method.Invoke( methodToExecute.instance, parameters );

				}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions