- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在玩 IEnumerable/<T>
和 IEnumerator/<T>
.在我的一个试验中,我试图分配一个 IEnumerable<T>
类型的返回值。值为 IEnumerator<T>
通过使用转换,然后尝试执行 MoveNext()
和 Current
.尽管转换没有出现错误,但我没有得到任何输出:
class Animal
{
public string AnimalType { get; set; }
public Animal(string animal_type)
{
AnimalType = animal_type;
}
}
class FarmCollection
{
readonly Animal[] _farm =
{ new Animal("duck"), new Animal("cow"), new Animal("sheep") };
public IEnumerable<Animal> GetEnumerable()
{
foreach (Animal a in _farm)
yield return a;
}
}
class Test
{
public static void Main()
{
FarmCollection farm = new FarCollection();
IEnumerator<Animal> enumerator = (IEnumerator<Animal>)farm.GetEnumerable();
while (enumerator.MoveNext())
{
Animal a = (Animal)enumerator.Current;
Console.WriteLine(a.AnimalType);
}
}
}
第一个问题:为什么我没有输出,而Main只是返回?
第二个问题:为什么要从 IEnumerable<Animal>
进行类型转换?至 IEnumerator<Animal>
没有发出编译错误?
最佳答案
这是你的 FarmCollection.GetEnumerable
反编译后的方法看起来像:
public IEnumerable<Animal> GetEnumerable()
{
FarmCollection.<GetEnumerable>d__0 <GetEnumerable>d__ =
new FarmCollection.<GetEnumerable>d__0(-2);
<GetEnumerable>d__.<>4__this = this;
return <GetEnumerable>d__;
}
类型FarmCollection.<GetEnumerable>d__0
也是由编译器生成的。参见 this article更多细节。这是这个类的样子:
[CompilerGenerated]
private sealed class <GetEnumerable>d__0 : IEnumerable<Animal>, IEnumerable, IEnumerator<Animal>, IEnumerator, IDisposable
{
private Animal <>2__current;
private int <>1__state;
private int <>l__initialThreadId;
public FarmCollection <>4__this;
public Animal <a>5__1;
public Animal[] <>7__wrap3;
public int <>7__wrap4;
Animal IEnumerator<Animal>.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
[DebuggerHidden]
IEnumerator<Animal> IEnumerable<Animal>.GetEnumerator()
{
FarmCollection.<GetEnumerable>d__0 <GetEnumerable>d__;
if (Environment.CurrentManagedThreadId == this.<>l__initialThreadId && this.<>1__state == -2)
{
this.<>1__state = 0;
<GetEnumerable>d__ = this;
}
else
{
<GetEnumerable>d__ = new FarmCollection.<GetEnumerable>d__0(0);
<GetEnumerable>d__.<>4__this = this.<>4__this;
}
return <GetEnumerable>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return this.System.Collections.Generic.IEnumerable<ConsoleApplication479.Animal>.GetEnumerator();
}
bool IEnumerator.MoveNext()
{
bool result;
try
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.<>1__state = 1;
this.<>7__wrap3 = this.<>4__this._farm;
this.<>7__wrap4 = 0;
goto IL_8D;
case 2:
this.<>1__state = 1;
this.<>7__wrap4++;
goto IL_8D;
}
goto IL_A9;
IL_8D:
if (this.<>7__wrap4 < this.<>7__wrap3.Length)
{
this.<a>5__1 = this.<>7__wrap3[this.<>7__wrap4];
this.<>2__current = this.<a>5__1;
this.<>1__state = 2;
result = true;
return result;
}
this.<>m__Finally2();
IL_A9:
result = false;
}
catch
{
this.System.IDisposable.Dispose();
throw;
}
return result;
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
void IDisposable.Dispose()
{
switch (this.<>1__state)
{
case 1:
break;
case 2:
break;
default:
return;
}
this.<>m__Finally2();
}
[DebuggerHidden]
public <GetEnumerable>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
private void <>m__Finally2()
{
this.<>1__state = -1;
}
}
因此在您的代码中,enumerator
变量指的是这种类型的对象。由于这种类型实现了 IEnumerator<Animal>
,这就解释了为什么转换没有失败。
现在,第二个问题。请注意 GetEnumerable
编译器生成的方法构造 FarmCollection.<GetEnumerable>d__0
实例并给出值 -2
给构造函数。这存储在 <>1__state
中多变的。现在,看看 MoveNext()
方法。它在 <>1__state
上有一个 switch 语句多变的。如果此类变量的值不是 0
或 2
, 那么该方法保证返回 false
这意味着枚举不会返回任何值。
注意 GetEnumerator()
此类中的方法将状态更改为 0 并返回相同的实例(在某些情况下,它返回状态为 0 的类的新实例),这将使 MoveNext
方法工作。
所以基本上是 MoveNext
如果不执行GetEnumerator()
,方法将无法工作.
关于c# - 从 IEnumerable 转换为 IEnumerator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39400002/
任何人都可以向我解释 IEnumerable 和 IEnumerator 之间的区别是什么, 以及如何使用它们? 谢谢!!! 最佳答案 通常,一个 IEnumerable是可以枚举的对象,例如列表或数
function TSomething.Concat(const E: IEnumerable>): IEnumerable; begin Result := TConcatIterator.Cr
我正试图找到解决这个问题的办法: 给定一个 IEnumerable> 我需要一个返回输入的方法/算法,但是如果多个 IEnumerable 具有相同的元素,则每个巧合/组只返回一个。 例如 I
我有一个有趣的问题:给定一个 IEnumerable , 是否有可能产生 IEnumerable> 的序列一次将相同的相邻字符串分组? 让我解释一下。 1。基本说明示例: 考虑以下 IEnumerab
我有课 public class Test { public void M1(IEnumerable> p) { } public void M2(IEnumerable)> p) {
我尝试解决下一个练习: 输入:整数列表 count >= 1;一些正整数 k 输出:此整数的所有可能元组,长度为 k ; 例如 输入: {1, 2}; k = 4 输出: { {1, 1, 1, 1
抱歉奇怪的标题。我想要实现的目标很简单: IEnumerable> listoflist; IEnumerable combined = listoflist.CombineStuff(); 例子:
公共(public)类项目 { ... public class Order { public List Items ... } public class Customer {
我有一个 IEnumerable>我想转换为单一维度集合的集合。是否可以使用通用扩展方法来实现这一点?现在我正在这样做以实现它。 List filteredCombinations = new Lis
我有一个 IEnumerable> CustomObject在哪里有一个 x (用作键(在本例中为 1 、 2 、 3 ))和 y值(value)。一些假数据: { { {1, 2}, {2, 4
我需要做的是选择嵌套元素列表,这是我的查询 returns IEnumerable>这是我的 linq 表达式: from a in (questions.Select(x => x.AnswerLi
如何使用 LINQ(或其他方式)将 IEnumerables 的 IEnumerable 拆分为一个平面 IEnumerable? 最佳答案 enumerable.SelectMany(x => x)
例如: public interface IEnumerable { IEnumerator GetEnumerator(); } //This interface allows the c
我对 Reflection.Emit 有疑问。我想要动态创建的类,它具有 ICollection 的简单实现。我定义的所有方法都很好,而不是接下来的两个: public IEnumerator Get
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Why was IEnumerable made covariant in C# 4? 我正在查看 MSDN
IEnumerator.MoveNext() 的实现是否预计会相对较快?或者如果“移动到下一项” 包括磁盘 IO、Web 请求或其他可能长时间运行的操作是否可以? 例如,我正在处理一个处理文档的项目,
以下代码创建了 List 的中间实例并在 yield 返回之前将值附加到它。有没有一种好的方法可以避免创建实例并直接 yield 返回单元格值? IEnumerable> GetStrValues()
我有两个 IEnumerable 对象,我想验证其中一个是否包含另一个的所有元素。 我正在使用 obj1.Intersect(obj2).Any() 但交集没有像我预期的那样工作。即使 obj2 中只
我正在尝试这个 MSDN page 上的例子.我试图更改 GetEnumerator 方法。我知道那似乎有些不对劲,但它符合要求然后就不会运行。错误是枚举器尚未启动,应该调用 MoveNext,但 它
我写过关于自定义 IEnumerator 的文章。从中生成 IEnumerable 的最简单方法是什么?理想的解决方案(一行代码)是是否有一些用于该目的的类。还是我必须自己创建? 最佳答案 不幸的是,
我是一名优秀的程序员,十分优秀!