繁体   English   中英

反射动态调用方法

[英]calling methods dynamically with reflection

我正在尝试在aspx.cs中调用方法,但收到带有消息的InvalidOperationException

无法对包含ContainsGenericParameters为true的类型或方法执行后期绑定操作。

我的代码是:

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

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

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

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

知道我在做什么错吗?

由于您要传递具体泛型类型dynamicType的实例workflowConfiguration dynamicType ,因此在调用将其用作参数的泛型方法时,需要使用其具体泛型参数。

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

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

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

你应该做:

Type[] listType = dynamicType.GetGenericArguments();

我认为您还需要将generic.Invoke()的返回值generic.Invoke()转换为Panel

还有另一种解决方案,不涉及通过反射调用方法。 看看这个:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM