Métodos de chamada que utilizam os nomes em C#

Tenho uma série de "empregos" na minha candidatura, onde cada emprego tem uma lista de métodos a que precisa de chamar, juntamente com os seus parâmetros. Essencialmente uma lista contendo o seguinte objeto é chamada:

string Name;
List<object> Parameters;
Então, basicamente, quando um trabalho é executado Eu quero enumerar através desta lista, e chamar os métodos relevantes. Por exemplo, se eu tiver um método como o seguinte:

TestMethod(string param1, int param2)

o meu objecto do método seria assim:

Name = TestMethod
Parameters = "astring", 3
É possível fazer isto? Imagino. a reflexão será a chave aqui.

Author: Chris, 2011-06-24

5 answers

Claro, podes fazê-lo assim.
public class Test
{
    public void Hello(string s) { Console.WriteLine("hello " + s); }
}

...

{
     Test t = new Test();
     typeof(Test).GetMethod("Hello").Invoke(t, new[] { "world" }); 

     // alternative if you don't know the type of the object:
     t.GetType().GetMethod("Hello").Invoke(t, new[] { "world" }); 
}

O segundo parâmetro de Invoce() é um array de objeto contendo todos os parâmetros para passar para o seu método.

Assumindo que os métodos pertencem todos à mesma classe, você poderia ter um método dessa classe algo como:
public void InvokeMethod(string methodName, List<object> args)
{
    GetType().GetMethod(methodName).Invoke(this, args.ToArray());
}
 39
Author: Igby Largeman, 2011-06-24 14:38:39

Se está a usar o. NET Framework 4, Veja dynamic , caso contrárioGetMethod e depois liga para Invoke de MethodInfo.

 1
Author: Kirill Polishchuk, 2011-06-24 14:22:56
NuGet para o resgate! PM> Install-Package dnpextensions

Uma vez que você tenha esse pacote em seu projeto, todos os objetos devem agora ter uma extensão .InvokeMethod(), que irá tomar o nome do método como uma string e qualquer número de parâmetros.

Isso usa tecnicamente "strings mágicas" para os nomes do método, então se você quisesse fortemente digitar o seu dicionário de método, você poderia fazer as chaves do tipo MethodInfo e obtê-las assim...

MethodInfo[] methodInfos = typeof(MyClass).GetMethods();
E depois podes fazer algo assim...
var methods = new Dictionary<MethodInfo, Object[]>();
foreach (var item in methods)
   item.key.Invoke(null, item.value);  
   // 'null' may need to be an instance of the object that
   // you are calling methods on if these are not static methods.

Ou você pode fazer alguma variação do bloco acima usando o dnpextensions que mencionei anteriormente.

 1
Author: jrizzo, 2011-06-24 14:43:28

Utilize MethodBase.Invocar () . Deve chegar ao. NET 2.0 com System.Reflection.

 0
Author: Kongress, 2011-06-24 14:23:31
Se você está usando ter que recorrer à reflexão, provavelmente há uma maneira melhor de realizar sua tarefa. Pode ser preciso um pouco mais de arquitetura, mas é possível. Lembra-te, ter mais código não é uma coisa má, especialmente quando complementa a legibilidade e a maneabilidade do teu código. A reflexão é difícil de entender para a maioria, e você perde a maior parte de sua segurança do tipo de tempo de compilação. No seu exemplo, você provavelmente poderia apenas sair impune com uma declaração switch e objetos distintos para cada método que você estava planejando chamar. por exemplo
// Have some object hold the type of method it plans on calling.
enum methodNames
{
   Method1,
   Method2
}

...
class someObject
{
   internal methodNames methodName {get; set;}
   internal object[] myParams;
}
...

//  Execute your object based on the enumeration value it references.
switch(someObject1.methodName)
{
   case Method1:
      Test.Method1(Int32.Parse(someObject1.myParams[0].ToString),someObject1.myParams[1].ToString());
      break;
   ...
}
Se sabes que só tens um conjunto distinto de possibilidades de método a usar, porque não te preparas antes do tempo?
 -1
Author: George Johnston, 2011-06-24 14:33:13