Search code examples
c#reflectionmethodinfo

Method invoke is returning 'parameter count mismatch' as error


I want to call a method by string. I got quite far until my code returns parameter count mismatch.

I know that neither my classInstance nor my method is null. I read that you need to put your Parameterarray into another array.

It seems just perfect, but then it gives me this error. The class of the method is located at Modules.Achievements.Achieve. methodname is the variable string that would equal with an existing method in the Achieve class.

    string userid = Modules.Users.GetCreatorId();
    var type = typeof(Modules.Achievements.Achieve);
    MethodInfo method = type.GetMethod(methodname);
    try
    {
      if ( method == null )
        return;
      object classInstance = Activator.CreateInstance(type, null);
      if ( classInstance == null ) 
        return;
      object[] parametersArray = new object[] { userid };
      var result = (Boolean)method.Invoke(classInstance, 
                                          new object[] { parametersArray });
      if ( result )
      {
        Console.WriteLine("succeeded.");
        return;
      }
      Console.WriteLine("incorrect steamid.");
      return;
    }
    catch ( Exception e )
    {
      Console.WriteLine($"error:{e.Message}");
    }
    Console.WriteLine("failed.");
    return;

My method should return a Boolean if something failed or not. The method only has one Parameter (String). In this case it is the userid that goes into the method as parameter.

Instead of returning anything, it detects an error before returning something. The error is from the method.Invoke(classInstance, new object[] { parametersArray });.

I googled parameter count mismatch on Reflection but all solutions I saw still give the same error. What can I do best?


Solution

  • Sins not a lot of useful info is provided, your best bet would be to do something like this to fix up the parameters, also your parametersArray should be passed in without it being part of another array.

    public void InvokeMethod()
    {
        var type = typeof(Modules.Achievements.Achieve);
    
        var method = type.GetMethod(methodname);
    
        if (method != null)
        {
            var instance = Activator.CreateInstance(type, null);
    
            if (instance != null)
            {
                var fixedParams = ParseParameters(method.GetParameters(), new object[] { Modules.Users.GetCreatorId() });
    
                if ((bool)method.Invoke(instance, fixedParams))
                {
                    Console.WriteLine("Success");                
                }
                else
                {
                    Console.WriteLine("Invalid Steam ID");
                }
                return;
            }
        }
        Console.WriteLine("Encountered an error!");
    }
    
    private object[] ParseParameters(ParameterInfo[] methodParams, object[] userParams)
    {
        int mLength = methodParams.Length;
    
        if (mLength > 0)
        {
            var objs = new object[mLength];
    
            if ((userParams == null) || (userParams.Length == 0))
            {
                for (int i = 0; i < mLength; i++)
                {
                    var mp = methodParams[i];
    
                    objs[i] = (mp.HasDefaultValue ? mp.DefaultValue : mp.ParameterType.IsClass ? null : Activator.CreateInstance(mp.ParameterType, null));
                }
            }
            else
            {
                 int uLength = userParams.Length;
    
                 if (uLength > mLength) { throw new ArgumentException("Too many params were specified"); }
    
                 for (int i = 0; i < uLength; i++)
                 {
                     objs[i] = Convert.ChangeType(userParams[i], methodParams[i].ParameterType);
                 }
    
                 if (uLength < mLength)
                 {
                     for (int i = uLength; i < mLength; i++)
                     {
                         var mp = methodParams[i];
    
                         objs[i] = (mp.HasDefaultValue ? mp.DefaultValue : mp.ParameterType.IsClass ? null : Activator.CreateInstance(mp.ParameterType, null));
                     }
                 }
            }
            return objs;
        }
        return null;
    }