【问题标题】:Unable to cast '<T>d__14`1[System.Object] to 'IEnumerable`1[System.Int32]'无法将 '<T>d__14`1[System.Object] 转换为 'IEnumerable`1[System.Int32]'
【发布时间】:2017-05-27 17:54:25
【问题描述】:

我正在尝试创建 IEnumerable 的生成器来设置 School.Foundation

这是我目前要填充的类型:

public class School
{
    public IEnumerable<int> Foundation;
}

到目前为止,这是我的生成器:

public static IEnumerable<T> GetEnumerable <T>(Func<T> f)
    {
        while(true)
        {
            yield return f();
        }
    }

所以我正在做的是以下反思:

Dictionary<string, Func<object>> funcMembers;

public static object Generator(String name, Type t)
{
    Func<object> func;
    if (funcMembers.TryGetValue(name, out func))
    {
         if (t.Name.StartsWith("IEnumerable"))
             return GetEnumerable(func);
    }
}

我进行了以下测试以检查它是否功能齐全:

    [TestMethod]
    public void Test_generator()
    {   
        private Dictionary<string, Func<object>> funcMembers = new Dictionary<string, Func<object>>();

        //adding the Field "Foundation" generator on the dictionary
        funcMembers.Add("Foundation", () => {return 4;}); 

        School s = new School();

        // calling my Generator that should return IEnumerable<int>
        s.Foundation = Generator(
                         "Foundation",
                          typeof(School).GetField("Foundation").

        Assert.IsNotNull(s.Foundation);
    }

我在线时出现以下错误:

s.Foundation = Generator(
                     "Foundation",
                      typeof(School).GetField("Foundation").

错误如下:

> Unable to cast object of type '<GetEnumerable>d__14`1[System.Object]'
> to type 'System.Collections.Generic.IEnumerable`1[System.Int32]'.

【问题讨论】:

    标签: c# reflection ienumerable yield system.reflection


    【解决方案1】:

    您的funcMembers 包含以下内容:

    funcMembers.Add("Foundation", () => {return 4;}); 
    

    右侧是匿名委托,无参数,返回常量4。它被隐式键入为Func&lt;object&gt;,因此可以将其添加到字典中。与所有委托一样,编译器将其编译为一个类,但由于它没有名称,因此会自动生成一个特殊名称“d__14`1[System.Object]”。

    然后,GeneratorGetEnumerable 方法似乎直接返回了这个委托对象,而不是调用它并获取 4 的值并将其包装到 IEnumerable 中。

    这个从GeneratorGetEnumerable 返回的委托然后被分配给s.Foundation,这会导致您注意到这个错误(因为委托的匿名类显然没有实现IEnumerable)。

    我敢打赌,您只需使用调试器就可以看到所有这些。为了更好地查看,请这样写:

       var tmp = Generator(
                         "Foundation",
                          typeof(School).GetField("Foundation")...
       s.Foundation = tmp;
    

    并观察 TMP 中的值,然后,诊断发生了什么(即,通过进入 Generator 并查看那里发生的情况)并修复它。

    旁注:这是您粘贴的这些代码片段。我无法告诉您更多有关您的问题的信息,因为您提供的代码包含严重错误(即Generator - 并非所有代码路径都返回值),有些行不完整(typeof(School).GetField("Foundation"). 的结尾在哪里?)等等.

    在这种情况下,请尝试提供实际编译的minimal complete example

    【讨论】:

      猜你喜欢
      • 2021-01-29
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多