使用动态?
时可以调用“IEnumerable / yield return”方法我问这个是因为当我调用“Test(States1.GetNames())”方法时,我收到了以下错误。
错误:“附加信息:'对象'不包含'GetEnumerator'的定义”
using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
namespace YieldDemo
{
public class States1
{
public static IEnumerable<string> GetNames()
{
yield return "Alabama";
yield return "Alaska";
yield return "Arizona";
yield return "Arkansas";
yield return "California";
yield return "Others ...";
}
}
public class States2
{
private static readonly IList<string> _names;
static States2()
{
_names = new List<string>() {"Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California",
"Others ..." };
}
public static IList<string> GetNames()
{
return _names;
}
}
public class Program
{
static void Main()
{
Test(States2.GetNames());
Test(States1.GetNames());
Console.ReadLine();
}
public static void Test(dynamic state)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Iterate(state);
stopwatch.Stop();
Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
}
public static void Iterate(dynamic itemList)
{
var enumerator = itemList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
}
}
由于
答案 0 :(得分:4)
问题是迭代器块实现使用显式接口实现来实现IEnumerable<T>
...并且显式接口实现通常不能很好地与动态类型一起使用。 (您不需要使用迭代器块来查看它。有关详细信息,请参阅my article on Gotchas in Dynamic Typing。)
您可以使用foreach
进行迭代:
public static void Iterate(dynamic itemList)
{
foreach (dynamic item in itemList)
{
Console.WriteLine(item);
}
}
这有额外的好处,它将为您处理迭代器,您以前的代码没有这样做:)
或者,您为Iterate
添加重载以获取IEnumerable
或IEnumerable<T>
,并让Test
内的执行时重载解析做正确的事(由于{{ 1}}也是state
。
答案 1 :(得分:0)
它失败是因为IEnumerable<string>
代码生成的yield
类explicitly implements其接口(包括您尝试使用的GetEnumerator
)。你可以这样调用这个方法:
public static void Iterate(dynamic itemList)
{
var enumerator = ((IEnumerable)itemList).GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
或者,既然你因为任何原因我不需要dynamic
,我可以在这里看到,也许只是:
public static void Iterate(IEnumerable itemList)
{
var enumerator = itemList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
或者
public static void Iterate<T>(IEnumerable<T> itemList)