繁体   English   中英

用methodInfo.Invoke调用的方法返回yield return

[英]Method invoked with methodInfo.Invoke returns yield return

我使用的是第三方包到.Net cms,从内部数据表示到POCO都是一种ORM。 为了使它起作用,我需要从GitHub中获取其源代码进行调试,然后看看有什么问题。 我发现存在对使用yield return的方法的反射MethodInfo.Invoke调用。 该方法的返回值应该使用property.SetValue()分配给POCO的属性。 此调用返回的null设置为属性会导致无效的映射结果。

我稍微改变了方法的逻辑以首先组成IEnumerable <>,然后按原样返回它,并使用普通返回,没有收益-然后一切开始正常工作。

我的问题是-由于此软件包已由其他人下载和使用,因此它被认为可以正常工作,而无需更改源代码-也许有某种方法可以处理以yield形式返回的Invoked方法? 我知道yield返回一个枚举数(状态机),该值将在某些IEnumerable上的foreach式循环中使用,但这是用于直接IEnumerable生成器方法调用,这是我第一次看到这种方法的反射调用。 谢谢。

更新:感谢@GeorgeVovos。 该插件为https://github.com/AliSheikhTaheri/Archetype-Mapper 导致问题的代码是:

  1. 调用部分:

      public void SetPropertyValue<T>(object fromObject, PropertyInfo property, T model, IUmbracoMapper mapper) { var fieldsets = GetArchetypeModel(fromObject); if (fieldsets != null) { var type = property.PropertyType.GetGenericArguments()[0]; var method = GetType().GetMethod("GetItems", BindingFlags.NonPublic | BindingFlags.Instance); var genericMethod = method.MakeGenericMethod(type); var items = genericMethod.Invoke(this, new object[] { fieldsets, mapper }); property.SetValue(model, items); } } 
  2. 方法:

      private IEnumerable<T> GetItems<T>(IEnumerable<ArchetypeFieldsetModel> fieldsets, IUmbracoMapper mapper) { foreach (var fieldset in fieldsets) { // Instantiate the T var instance = (T)Activator.CreateInstance(typeof(T)); // make a dictionary of property alias and value var dictionary = fieldset.Properties.ToDictionary(property => FirstToUpper(property.Alias), property => property.Value); // If fieldset name is the same as instance type then lets map it to the instance if (instance.GetType().Name.ToLower() == fieldset.Alias.ToLower()) { mapper.Map(dictionary, (object)instance); } else // if not then lets find a property with the same name as fieldset name { var property = instance.GetType().GetProperties().FirstOrDefault(x => x.Name.ToLower() == fieldset.Alias.ToLower()); if (property != null) { var propertyClass = Activator.CreateInstance(property.PropertyType); mapper.Map(dictionary, propertyClass); var propertyInfo = instance.GetType().GetProperty(property.Name); propertyInfo.SetValue(instance, Convert.ChangeType(propertyClass, propertyInfo.PropertyType)); } } yield return instance; } } 

我明白你的回答。 看起来当我开始使用该插件时,我的代码(模型)定义的属性定义不正确,并装饰有属性,该属性的插件代码映射了CMS中的数据。 据我了解,原始插件代码提供了懒惰的数据获取,而我的更改却使它变得急切。 但是,如果一开始我将属性定义为可枚举,就不会出现问题。

非常感谢!

方法的调用方式无关紧要(是否使用反射)。
它按预期工作。

using System;
using System.Collections.Generic;
using System.Reflection;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass m = new MyClass();

            MethodInfo method = m.GetType().GetMethod("MyMethod");
            var result = (IEnumerable<string>)method.Invoke(m, null);
            foreach (var item in result)
                Console.WriteLine("Printing:" + (item ?? "null"));

            Console.ReadLine();
        }
    }

    public class MyClass
    {
        public IEnumerable<string> MyMethod()
        {
            Console.WriteLine("Returning null");
            yield return null;
            Console.WriteLine("Returning 111");
            yield return "111";
            Console.WriteLine("Returning 222");
            yield return "222";
            Console.WriteLine("Returning 333");
            yield return "333";
        }
    }
}

打印:
在此处输入图片说明

您可以提供一个代码示例来确切地了解您的问题吗?

暂无
暂无

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

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