我想知道为什么GetEnumerator()方法是从IEnumerator中分解出来并放在IEnumerable中的.在我看来,将所有枚举器方法保留在IEnumerator中会更有意义.
谢谢,
斯科特
我使用以下代码使myClass使用foreach.但我对编程很新,并且在理解下面的代码时遇到了一些困难.我在评论中描述了我的问题.我很感激提供一些信息.
public class MyClass : IEnumerable<string>
{
//1) What is IEnumerator for?
// Whats the difference between IEnumerator and IEnumerable
public IEnumerator<string> GetEnumerator()
{
yield return "first";
yield return "second";
}
//2) What is it for? It just calls above method
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
//3) Lastly what benefits I have from implementing genetic interface
//IEnumerable<string> instead of just IEnumerable
Run Code Online (Sandbox Code Playgroud) 有没有人有一个如何在C++/CLI中实现IEnumerable和IEnumerator的有效的分步示例?或者,是否有人知道如何修复MS Connect中的以下代码,这些代码无法在Visual Studio 2005中编译?
using namespace System;
using namespace System::Collections::Generic;
generic <class T>
public ref struct MyArray : public IEnumerable<T>
{
MyArray( array<T>^ d )
{
data = d;
}
ref struct enumerator : IEnumerator<T>
{
enumerator( MyArray^ myArr )
{
colInst = myArr;
currentIndex = -1;
}
bool MoveNext()
{
if( currentIndex < colInst->data->Length - 1 )
{
currentIndex++;
return true;
}
return false;
}
property T Current
{
T get()
{
return colInst->data[currentIndex];
}
};
// This …Run Code Online (Sandbox Code Playgroud) 我有一个实现的类IEnumerator<string>.见下文:
public class MyClass : IEnumerator<string>
{
public bool MoveNext()
{
//....
}
//Implement other required methods....
//Confusion lies below:
public string Current { get { return this.CurrentLine; } }
//Why do I need to implement IEnumerator.Current?! In my tests, it's not even called during my iteration
object IEnumerator.Current { get { throw new NotImplementedException(); } }
}
Run Code Online (Sandbox Code Playgroud)
除了IEnumerator<T>接口和IEnumerator接口(IEnumerator<T>继承)上都存在.Current属性之外,实现它的重点是什么?如上所述它甚至没有被称为.
我有时会发现自己正在考虑在引用时使用哪个词IEnumerable<Foo>.我不认为我在阅读时会看到一致的命名.
IEnumerable<Foo>:这是一个类型名称.在思考或使用句子时没有用处.
收藏:它是有效的,但并不是随处可见.虽然我们有System.Collections命名空间.
顺序:它也是有效的,可能更好地定义它.
枚举器或迭代器:他们强调操作,很少使用.
什么是最合适的?你在代码中读到了什么?
我很好奇是否IEnumerable与IObservable引擎盖下有什么不同.我分别理解了pull和push模式但是C#在内存等方面如何通知订阅者(对于IObservable)它应该在内存中接收下一位数据来处理?观察到的实例如何知道它有一个数据的变化推送到订阅者.
我的问题来自于我正在从文件中读取行的测试.该文件总共约为6Mb.
标准时间:4.7s,行:36587
Rx拍摄时间:0.68秒,行:36587
Rx如何能够大规模地改进文件中每条线的正常迭代?
private static void ReadStandardFile()
{
var timer = Stopwatch.StartNew();
var linesProcessed = 0;
foreach (var l in ReadLines(new FileStream(_filePath, FileMode.Open)))
{
var s = l.Split(',');
linesProcessed++;
}
timer.Stop();
_log.DebugFormat("Standard Time Taken: {0}s, lines: {1}",
timer.Elapsed.ToString(), linesProcessed);
}
private static void ReadRxFile()
{
var timer = Stopwatch.StartNew();
var linesProcessed = 0;
var query = ReadLines(new FileStream(_filePath, FileMode.Open)).ToObservable();
using (query.Subscribe((line) =>
{
var s = line.Split(',');
linesProcessed++;
}));
timer.Stop();
_log.DebugFormat("Rx Time Taken: {0}s, …Run Code Online (Sandbox Code Playgroud) 这是相当长一段时间,我一直在试图了解背后的想法IEnumerable和IEnumerator.我阅读了网上可以找到的所有问题和答案,特别是StackOverflow,但我并不满意.我明白了我应该如何使用这些接口,但不是为什么这样使用它们.
我认为我误解的本质是我们需要两个接口进行一次操作.我意识到,如果两者都需要,可能还不够.所以我采用了"硬编码"等价物foreach(正如我在这里找到的):
while (enumerator.MoveNext())
{
object item = enumerator.Current;
// logic
}
Run Code Online (Sandbox Code Playgroud)
并试图让它与一个界面一起工作,认为某些事情会出错,这将使我理解为什么需要另一个界面.
所以我创建了一个集合类,并实现了IForeachable:
class Collection : IForeachable
{
private int[] array = { 1, 2, 3, 4, 5 };
private int index = -1;
public int Current => array[index];
public bool MoveNext()
{
if (index < array.Length - 1)
{
index++;
return true;
}
index = -1;
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用foreach …
我想了解如何处理链查询.例如,让我们考虑以下查询
var sumOfRoots = numbers //IEnum0
.Where(x => x > 0) //IEnum1
.Select(x => Math.Sqrt(x)) //IEnum2
.Select(x => Math.Exp(x)) //IEnum3
.Sum();
Run Code Online (Sandbox Code Playgroud)
例如 numbers={-1, 4, 9 }.
这是幕后发生的事情:
1.获得所有普查员(正面通行证)
numbers调用GetEnumerator()返回(让我们用它来表示)IEnum0实例IEnum0GetEnumerator()返回IEnum1实例的调用IEnum1GetEnumerator()返回IEnum2实例的调用IEnum2GetEnumerator()返回IEnum3实例的调用2.调用MoveNext(向后传递)
.Sum()呼吁MoveNext()对IEnum3IEnum3呼吁MoveNext()对IEnum2IEnum2呼吁MoveNext()对IEnum1IEnum1呼吁MoveNext()对IEnum03.从MoveNext返回(前后传球)
IEnum0移动到元素-1并返回true.IEnum1检查是否-1 …为什么接下来的代码会产生循环挂起?
var x = new
{
Items = new List<int> { 1, 2, 3 }.GetEnumerator()
};
while (x.Items.MoveNext())
Console.WriteLine(x.Items.Current);
Run Code Online (Sandbox Code Playgroud)
如果我在 x 初始化后得到枚举器,则一切正常:
var x = new
{
Items = new List<int> { 1, 2, 3 }
};
var enumerator = x.Items.GetEnumerator();
while (enumerator.MoveNext())
Console.WriteLine(enumerator.Current);
Run Code Online (Sandbox Code Playgroud)
尝试反编译这两个代码块,但不明白原因:
List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
intList.Add(3);
var data1 = new \u003C\u003Ef__AnonymousType0<List<int>.Enumerator>(intList.GetEnumerator());
while (true)
{
List<int>.Enumerator items = data1.Items;
if (items.MoveNext())
{
items = data1.Items;
Console.WriteLine(items.Current);
}
else
break;
}
List<int> Items = new …Run Code Online (Sandbox Code Playgroud) 我当前的应用程序中有命令层次结构.
public interface ICommand
{
void Execute();
}
Run Code Online (Sandbox Code Playgroud)
所以,有些命令是有状态的,有些则不是.
我需要在循环方式中枚举IEnumerable,以便在命令执行期间执行某些命令.
public class GetNumberCommand : ICommand
{
public GetNumberCommand()
{
List<int> numbers = new List<int>
{
1, 2, 3
};
}
public void Execute()
{
// Circular iteration here.
// 1 => 2 => 3 => 1 => 2 => 3 => ...
}
public void Stop()
{
// Log current value. (2 for example)
}
}
Run Code Online (Sandbox Code Playgroud)
Execute 被不时调用,因此有必要存储迭代状态.
如何实现循环枚举?
我找到了两个解决方案:
使用IEnumerator<T>界面.看起来像:
if (!_enumerator.MoveNext())
{
_enumerator.Reset();
_enumerator.MoveNext();
}
Run Code Online (Sandbox Code Playgroud)使用循环 …
ienumerator ×10
c# ×8
ienumerable ×7
.net ×4
linq ×2
c++-cli ×1
foreach ×1
iterator ×1
list ×1