2016-06-10 6 views
1

Ich versuche, eine Methode in einem aspx.cs zu nennen, aber ein InvalidOperationException mit NachrichtAufrufe von Methoden dynamisch mit Reflexion

Spät gebunden Operationen können nicht auf Typen oder Methoden für durchgeführt werden, bekommen die Contains wahr sind.

Mein Code ist:

protected void BuildSurface(int newValue) 
{ 
    IEnumerable<dynamic> models = InitializeConfigurationForWorkflow(newValue); 
    List<Panel> panelList = new List<Panel>(); 

    foreach (dynamic workflowConfiguration in models) 
    { 
     Type dynamicType = workflowConfiguration.GetType(); 

     if (dynamicType.IsGenericType) 
     { 
      Type genericDynamicType = dynamicType.GetGenericTypeDefinition(); 

      string methodName = null; 
      if (genericDynamicType.In(typeof(List<>), typeof(IEnumerable<>), typeof(IList<>))) 
       methodName = "GenerateListPanel"; 
      else if (genericDynamicType == typeof(Dictionary<,>)) 
       methodName = "GenerateDictionaryPanel"; 

      if (methodName.IsNullOrEmpty()) continue; 

      Type[] listType = genericDynamicType.GetGenericArguments(); 
      MethodInfo method = typeof(_admin_WorkflowConfiguration) 
       .GetMethods() 
       .Where(w => w.Name.Equals(methodName)) 
       .First(); 

      MethodInfo generic = method.MakeGenericMethod(listType); 
      panelList.Add(generic.Invoke(this, workflowConfiguration})); // here the error appears 
     } 
    } 
} 

meine Methoden, die aussehen wie diese aufgerufen wird:

public Panel GenerateListPanel<T>(IEnumerable<T> workflowConfiguration) 
{ 
    Panel panel = new Panel(); 
    return panel; 
} 

Der dynamisch-Wert ist ein json, die entweder Wörterbuch oder Liste deserialisiert wird .

Irgendeine Idee, was ich falsch mache?

+2

Sie nicht wollen 'Type [] listtype = dynamicType.GetGenericArguments();' – dbc

Antwort

1

Da Sie eine Instanz workflowConfiguration eines konkreten generischen Typs dynamicType übergeben, müssen Sie ihre konkreten generischen Argumente beim Aufrufen einer generischen Methode verwenden, die sie als Argument verwendet.

Wenn also Ihre Methoden GenerateListPanel und GenerateDictionaryPanel haben Unterschriften wie:

public Panel GenerateListPanel<T>(IEnumerable<T> workflowConfiguration) 

public Panel GenerateDictionaryPanel<TKey, TValue>(IDictionary<TKey, TValue> workflowConfiguration) 

Sie tun sollten:

Type[] listType = dynamicType.GetGenericArguments(); 

Ich glaube, Sie müssen auch die Rückkehr von generic.Invoke() zu einem Panel gegossen.

+0

Sie sind ein Genie! :) Danke, Mann! Ich musste auch 'workflowConfiguration' in' neues Objekt [] {workflowConfiguration} 'beim Aufruf von 'Invoke' ändern. –

1

Es gibt eine andere Lösung, die keine Aufrufmethode mit Reflektion beinhaltet. Werfen Sie einen Blick auf diese:

if (dynamicType.IsGenericType) 
      { 
       var genericDynamicType = dynamicType.GetGenericTypeDefinition(); 

       Func<Panel> generatePanelMethod = null; 
       if (genericDynamicType.In(typeof (List<>), typeof (IEnumerable<>), typeof (IList<>))) 
        generatePanelMethod =() => this.GenerateListPanel(workflowConfiguration); 
       else if (genericDynamicType == typeof(Dictionary<,>)) 
        generatePanelMethod =() => this.GenerateDictionaryPanel(workflowConfiguration); 

       if (generatePanelMethod == null) continue; 

       panelList.Add(generatePanelMethod()); 
      } 
+0

Wow, das sieht wirklich gut aus! Danke für diese Lösung :) Hier haben meine +1: D –

Verwandte Themen