我想知道使用yield return而不是返回列表是否存在任何并发(现在或将来)或性能优势.请参阅以下示例
处理方法
void Page_Load()
{
foreach(var item in GetPostedItems())
Process(item);
}
Run Code Online (Sandbox Code Playgroud)
使用收益率回报
IEnumerable<string> GetPostedItems()
{
yield return Item1.Text;
yield return Item2.Text;
yield return Item3.Text;
}
Run Code Online (Sandbox Code Playgroud)
返回一个清单
IEnumerable<string> GetPostedItems()
{
var list = new List<string>();
list.Add(Item1.Text);
list.Add(Item2.Text);
list.Add(Item3.Text);
return list;
}
Run Code Online (Sandbox Code Playgroud) 我正在学习F#,我真的很喜欢yield!(yield-bang)运算符.不仅因为它的名字,而且它当然也是它的作用.
的yield!操作者基本上可以让你产生序列的所有元素从一个序列的表达.这对于编写枚举器很有用.由于我经常遇到大而复杂的调查员,我对策略很感兴趣,我们可以用它来分解它们,并从简单的枚举器中编写它们.
不幸的是,yield!C#中没有运营商.据我了解,它的作用就像一foreach (var x in source) yield x;本书,但我正在阅读的书(Petricek的真实世界F# - Manning)表明它有更好的表现......
为了在C#中实现类似的构造,我已经探索了多种方式,但是它们都没有像yield!运算符那样简洁,我也不确定它们的复杂性.如果我的BigO号码正确,有人可以提供输入吗?
将枚举器分解为多个私有枚举器,然后从公共枚举器中生成每个元素:
foreach (var x in part1()) yield x
foreach (var x in part2()) yield x
Run Code Online (Sandbox Code Playgroud)
这将有效地导致每个元素的"双倍收益".那是O(2n)吗?(或者可能更糟?)无论如何,使用这种方法阻止我使用yield break;我的任何子部分.
将枚举器分解为多个私有枚举器,然后从公共枚举器中连接所有私有枚举器:
return part1().Concat(part2())
Run Code Online (Sandbox Code Playgroud)
我相信这与上述解决方案没有什么不同,因为它Concat()是按照我上面概述的方式实现的.
还有其他选择吗?
我是一名VB.Net开发人员,在C#中有点新手,在查看C#文档时,我通过迭代器和生成器来了,无法完全理解使用,我有任何人可以解释(在vb中有洞察力;如果可能的话)
关于如何实现双向枚举器(这里,这里)的问题已被问过几次.我的问题不是如何(对于大多数情况来说这是微不足道的),但为什么 .NET平台中不存在这样的类型.
public interface IBidirectionalEnumerator<T> : IEnumerator<T>
{
bool MovePrev();
}
Run Code Online (Sandbox Code Playgroud)
显然,有许多集合类型无法实现这一点,因为它MoveNext()是破坏性的或改变底层集合的状态.但反过来,很多类型可以平凡实现这一点(List,IList,LinkedList,array).
为什么不存在这种类型?
我试图弄清楚Ruby如何处理产生多个参数的链接枚举器.看一下这个片段:
a = ['a', 'b', 'c']
a.each_with_index.select{|pr| p pr}
# prints:
# ["a", 0]
# ["b", 1]
# ["c", 2]
a.each_with_index.map{|pr| p pr}
# prints:
# "a"
# "b"
# "c"
Run Code Online (Sandbox Code Playgroud)
为什么select将参数作为数组生成,而将map它们作为两个单独的参数生成?
这个问题不是关于如何在Ruby 1.9.1中使用枚举器,而是我很好奇它们是如何工作的.这是一些代码:
class Bunk
def initialize
@h = [*1..100]
end
def each
if !block_given?
enum_for(:each)
else
0.upto(@h.length) { |i|
yield @h[i]
}
end
end
end
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我可以使用e = Bunk.new.each,然后e.next,e.next获取每个连续的元素,但它究竟是如何暂停执行然后在正确的位置恢复?
我知道,如果0.upto用Fiber.yield它替换的产量很容易理解,但这不是这里的情况.这是一个普通的老yield,所以它是如何工作的?
我看了enumerator.c,但对我来说这是不可理解的.也许有人可以在Ruby中提供一个实现,使用光纤,而不是1.8.6样式的基于延续的枚举器,这一切都清楚了吗?
我正在测试一些同步结构,我注意到一些困扰我的东西.当我在同时写入一个集合时枚举它时,它抛出了异常(这是预期的),但是当我使用for循环遍历集合时,它没有.有人可以解释一下吗?我认为List不允许读者和作者同时操作.我希望循环遍历集合以展示与使用枚举器相同的行为.
更新:这是一个纯粹的学术练习.我强调,如果列表同时写入列表是很糟糕的.我也明白我需要一个同步结构.我的问题是关于为什么一个操作会像预期的那样抛出一个异常,而另一个却没有.
代码如下:
class Program
{
private static List<string> _collection = new List<string>();
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(AddItems), null);
System.Threading.Thread.Sleep(5000);
ThreadPool.QueueUserWorkItem(new WaitCallback(DisplayItems), null);
Console.ReadLine();
}
public static void AddItems(object state_)
{
for (int i = 1; i <= 50; i++)
{
_collection.Add(i.ToString());
Console.WriteLine("Adding " + i);
System.Threading.Thread.Sleep(150);
}
}
public static void DisplayItems(object state_)
{
// This will not throw an exception
//for (int i = 0; i < _collection.Count; i++)
//{
// Console.WriteLine("Reading " + _collection[i]);
// …Run Code Online (Sandbox Code Playgroud) foreach循环是否使用接口IEnumerator,IEnumerable仅用于迭代自定义类型(类)的对象,还是用于迭代内置类型(在幕后)?
我想现在ASP Classic/VB6 FOR EACH循环如何工作.我知道.NET IEnumberable/IEnumerator涉及到了,但是VB6/ASP Classic是如何做到的呢?
谢谢!
我试图n使用Ruby枚举器获取下一个数量的元素,使用:
a = [1, 2, 3, 4, 5, 6]
enum = a.each
enum.next(2) # expecting [1, 2]
enum.next(2) # expecting [3, 4]
Run Code Online (Sandbox Code Playgroud)
但#next不支持这一点.还有另一种方法可以做到吗?或者我该怎么办?
什么是正确的Ruby方法呢?
enumerators ×11
c# ×6
.net ×4
ruby ×3
foreach ×2
yield ×2
asp-classic ×1
block ×1
conduit ×1
f# ×1
fiber ×1
generator ×1
haskell ×1
ienumerable ×1
ienumerator ×1
interface ×1
iterator ×1
list ×1
ruby-1.9 ×1
vb6 ×1