用反射动态调用方法

时间:2016-06-10 10:39:29

标签: c# asp.net webforms

我正在尝试在aspx.cs中调用一个方法但是使用消息<{1}}获取

  

无法对类型或方法执行后期绑定操作   ContainsGenericParameters是真的。

我的代码是:

InvalidOperationException

我将调用的方法如下所示:

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
        }
    }
}

动态值是一个json,可以反序列化为Dictionary或List。

知道我做错了吗?

2 个答案:

答案 0 :(得分:1)

由于您传递的是具体泛型类型private void chartControl1_CustomDrawAxisLabel(object sender, CustomDrawAxisLabelEventArgs e) { AxisBase axis = e.Item.Axis; if (axis is AxisX) { e.Item.Text = e.Item.Text.Substring(0,2) ; } } 的实例workflowConfiguration,因此需要在调用将其用作参数的泛型方法时使用其具体的泛型参数。

因此,如果您的方法dynamicTypeGenerateListPanel具有以下签名:

GenerateDictionaryPanel

你应该这样做:

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

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

我认为您还需要将Type[] listType = dynamicType.GetGenericArguments(); 的返回值转换为generic.Invoke()

答案 1 :(得分:1)

还有一个不涉及使用反射调用方法的解决方案。看看这个:

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());
            }