-
-
Notifications
You must be signed in to change notification settings - Fork 256
Open
Description
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
Labels
No labels