以下代码段显示iterator
C ++ lib中的std::vector
。什么是C#相当于此?我可以简单地遍历向量中的每个项目,考虑到它不是链表吗?迭代器究竟在这做什么以及如何在C#中执行等效操作?完整代码为here。
std::vector<KMeanCluster>::iterator closest_cluster = clusters.begin();
// Figure out which cluster this color is closest to in RGB space.
for (std::vector<KMeanCluster>::iterator cluster = clusters.begin();
cluster != clusters.end(); ++cluster) {
uint distance_sqr = cluster->GetDistanceSqr(r, g, b);
if (distance_sqr < distance_sqr_to_closest_cluster) {
distance_sqr_to_closest_cluster = distance_sqr;
closest_cluster = cluster;
}
}
答案 0 :(得分:6)
C ++标准库迭代器的定义方式类似于遍历集合的指针。在C#中,实现IEnumerable
的每个集合都可以在foreach
循环中迭代。除此之外,您仍然可以使用Enumerator
在C#中执行类似于C ++迭代器的操作(这在大多数情况下会使事情变得更难):
IEnumerable<int> myCollection = new List<int> { 1, 2, 3 };
var enumerator = myCollection.GetEnumerator();
while(enumerator.MoveNext())
Console.WriteLine(enumerator.Current);
实际上,上面是foreach
循环在引擎盖下迭代的方式。
foreach(int num in myCollection)
Console.WriteLine(num);
因此,就您的代码而言,这是完全(但难以编码和理解)的等价物:
IEnumerator<KMeanCluster> closest_cluster = clusters.GetEnumerator();
while (closest_cluster.MoveNext())
{
uint distance_sqr = closest_cluster.Current.GetDistanceSqr(r, g, b);
if (distance_sqr < distance_sqr_to_closest_cluster)
{
distance_sqr_to_closest_cluster = distance_sqr;
closest_cluster = cluster;
}
}
这是最简单的等价物:
foreach(KMeanCluster closest_cluster in clusters)
{
uint distance_sqr = closest_cluster.GetDistanceSqr(r, g, b);
if (distance_sqr < distance_sqr_to_closest_cluster)
{
distance_sqr_to_closest_cluster = distance_sqr;
closest_cluster = cluster;
}
}
答案 1 :(得分:2)
迭代器基本上是一个允许对容器进行串行,非随机访问的对象。 无论如何:你可以在C#中使用普通循环。 foreach循环更接近C ++原始语法
答案 2 :(得分:2)
在C#中,这可能看起来像:
var closest_cluster = clusters.FirstOrDefault();
foreach (var cluster in clusters)
{
uint distance_sqr = cluster.GetDistanceSqr(r, g, b);
if (distance_sqr < distance_sqr_to_closest_cluster)
{
distance_sqr_to_closest_cluster = distance_sqr;
closest_cluster = cluster;
}
}
foreach
运算符的作用是使用下面的IEnumerator
,这相当于你的迭代器。
答案 3 :(得分:2)
通用集合 - IEnumerator<T>
支持对泛型集合的简单迭代。
非通用集合 - IEnumerator
支持对非泛型集合的简单迭代。
这些是接口,应该继承并覆盖。 MoveNext
和Reset
等方法。然后你可以在循环中使用该类。
答案 4 :(得分:1)
C#中有一个iterator
构造,但在这种情况下,您不需要直接访问它,而是使用foreach
循环。代码可能看起来像这样。
Cluster closestCluster = clusters.firstOrDefault();
foreach (Cluster currentCluster in clusters)
{
//Distance logic
if (distanceSqr < distanceSqrToClosestCluster)
{
closestCluster = currentCluster;
}
}
foreach
在内部通过IEnumerable<Cluster>
接口