215 votes

Réflexion : Comment faire pour appeler la méthode avec paramètres

Je suis en train d'appeler une méthode par réflexion avec les paramètres et j'obtiens un "objet ne correspond pas à la cible de type". Si j'invoque une méthode sans paramètres, il fonctionne très bien. Basé sur le code suivant si j'ai appeler la méthode Test("TestNoParameters"), il fonctionne très bien. Cependant si je l'appelle de Test("Run"), j'ai eu une exception. Est quelque chose de mal avec mon code?

Mon but initial était de passer un tableau d'objets (p. ex. public void Run(object[] options) mais cela ne fonctionne pas et j'ai essayé quelque chose de plus simple chaîne de caractères, sans succès.

//Assembly1.dll
namespace TestAssembly
{
    public class Main
    {
        public void Run(string parameters)
        { 
            // Do something... 
        }
        public void TestNoParameters()
        {
            // Do something... 
        }
    }
}

//Executing Assembly.exe
public class TestReflection
{
    public void Test(string methodName)
    {
        Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
        Type type = assembly.GetType("TestAssembly.Main");
        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod(methodName);
            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);
                if (parameters.Length == 0)
                {
                    //This works fine
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    //The invoke does NOT work it throws "Object does not match target type"             
                    result = methodInfo.Invoke(methodInfo, parametersArray);
                }
            }
        }
    }
}

251voto

womp Points 71924

Remplacez « methodInfo » « classInstance », tout comme dans l’appel avec le tableau de paramètre null.

29voto

Oleg I. Points 512

Vous avez un bug là

Il devrait être

24voto

Jason Points 125291

Une erreur fondamentale est ici :

Vous appelez la méthode sur une instance de `` . Vous devez passer une instance du type d’objet que vous souhaitez appeler sur.

12voto

Martin Kool Points 1757

La solution fournie ne fonctionne pas pour les instances de types chargés à partir d'une distance de l'assemblée. Pour ce faire, voici une solution qui fonctionne dans toutes les situations, ce qui implique un type explicite re-mappage du type retourné par la méthode CreateInstance appel.

C'est la façon dont j'ai besoin pour créer mon classInstance, comme il était situé dans une région éloignée de l'assemblée.

// sample of my CreateInstance call with an explicit assembly reference
object classInstance = Activator.CreateInstance(assemblyName, type.FullName); 

Cependant, même avec la réponse ci-dessus, vous auriez toujours obtenir la même erreur. Voici comment faire:

// first, create a handle instead of the actual object
ObjectHandle classInstanceHandle = Activator.CreateInstance(assemblyName, type.FullName);
// unwrap the real slim-shady
object classInstance = classInstanceHandle.Unwrap(); 
// re-map the type to that of the object we retrieved
type = classInstace.GetType(); 

Ensuite faire comme les autres utilisateurs mentionnées ici.

5voto

Nick N. Points 3939

Je voudrais l’utiliser comme ça, son chemin plus court et il ne donnera pas tous les problèmes

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X