[功能请求]“首先:” "最后:" “foreach”中的部分块 [英] [Feature Request] "first:" "last:" sections in a "foreach" block

查看:52
本文介绍了[功能请求]“首先:” "最后:" “foreach”中的部分块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想就C#

语言的新功能提出以下建议。我与微软的C#团队没有关系。我在这里发布

来收集输入以改进它,在开源中方式,并在一个

尝试建立一个支持地面膨胀,以说服微软的人们添加它。

提案: "第一:" "最后:" foreach中的部分块


问题:

foreach语句允许遍历

集合的所有元素。但是,通常集合的第一个或最后一个元素必须与集合中的其他元素不同地处理。例如,如果

我们生成了一个要显示的项目列表,那么除了最后一个项目之外,我们还需要一个逗号$
。在这些情况下,不能使用foreach,并且可以使用的替代品通常是丑陋的,并且通常效率低于预期。需要保持与C#概念一致的优雅解决方案。


建议:

我建议添加四个新关键字(仅在foreach块内可用)到

将编译器指向我们的确切意图。 "第一:" "最后:" " other:"

" all:"


示例:

foreach(Person p in personCollection)

{

优先:

Console.WriteLine(" Names:{0},",p.Name");

其他:

Console.WriteLine(" {0},",p.Name");

last:

Console.WriteLine(" {0}",p.Name");

}

假设一个不在其中一个关键字之前的块是一个

" all:"块,完全和现在的情况一样。


分析:

该功能的优点:

它解决了一个问题优雅的方式,保持设计概念

C#。

它完全由编译器处理,因此它对代码具有零效果

不使用它,它不需要更改类框架或

CLR。 (这些是其他建议的解决方案的问题)


缺点:

它需要四个关键字,虽然这可以减少到三个

(消除all:)并且,它们每个都对上下文非常敏感,因此

与用户定义的标识符冲突的可能性不大。


实施:

目前,foreach构造主要是语法糖。大约一段时间

循环使用IEnumerator,这样代码写成

foreach(int i in arry)

{

Console.WriteLine(i);

}


编译就像编写它一样:

IEnumerator n = arry.GetEnumerator();

while(n.MoveNext())

{

int i =(int)n.Current ;

Console.WriteLine(i);

}


同样,使用这些块的代码也可以直接翻译:

foreach(int in arry)

{

First:

Console.WriteLine(" {0 } - first",i);

其他:

Console.WriteLine(i);

}


编译为:

IEnumerator n = arry.GetEnumerator();

if(n.MoveNext())

{

int i =(int)n.Current;

Console.WriteLine(" {0} - first",i);

while(n.MoveNext())

{

i =(int)n.Current;

Console.WriteLine(i);

}

}

(last:的内部表示形式块更多涉及,但

仍然基本上是直截了当的)


任何意见建议将不胜感激。


真相,

James Curran

MVP(for .um.VC ++)

I''d like to make the following proposal for a new feature for the C#
language. I have no connection with the C# team at Microsoft. I''m posting
it here to gather input to refine it, in an "open Source" manner, and in an
attempt to build a ground-swell of support to convince the folks at
Microsoft to add it.
Proposal: "first:" "last:" sections in a "foreach" block

The problem:
The foreach statement allows iterating over all the elements of a
collection. However, often the first or last element of the collection must
be handled differently than the others in the collection. For example, if
we were generating a list of items for display, we''d want a comma after
every item except the last. In these cases, foreach cannot be used, and the
alternates which can be used are generally ugly and often less efficient
than foreach. An elegant solution keeping with the concept of C# is needed.

The proposal:
I suggest adding four new keywords (only available inside foreach block) to
direct the compiler to our exact intentions. "first:" "last:" "other:"
"all:"

Example:
foreach (Person p in personCollection)
{
first:
Console.WriteLine("Names: {0},", p.Name");
other:
Console.WriteLine(" {0},", p.Name");
last:
Console.WriteLine(" {0}", p.Name");
}
A block not preceeded by one of those keywords would be assumed to be an
"all:" block, exact as is the case now.

Analysis:
The advantages of the feature:
It solves a problem in an elegant way, keeping with the design concepts of
C#.
It is handled entirely by the compiler, so that it has ZERO effect on code
that does not use it, and it requires no changes to the class framework or
the CLR. (These were problems with other suggested solutions for this)

The disadvantages:
It requires four keywords, although this could be reduced to three
(eliminating "all:") and, they would each be very context sensitive, so the
conflicts with user-defined identifiers is unlikely.

Implementation:
Presently, a foreach construct is largely "syntactic sugar" around a while
loop using an IEnumerator, such that code written as
foreach (int i in arry)
{
Console.WriteLine(i);
}

Would be compiled much as if it were written:
IEnumerator n = arry.GetEnumerator();
while(n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine(i);
}

Similarly, code using these blocks would also have a direct translation:
foreach (int i in arry)
{
First:
Console.WriteLine("{0} - first", i);
Others:
Console.WriteLine(i);
}

Would be compiled as:
IEnumerator n = arry.GetEnumerator();
if (n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine("{0}-- first ", i);
while(n.MoveNext())
{
i = (int) n.Current;
Console.WriteLine(i);
}
}
(The internal representation of a "last:" block is a bit more involved, but
still basically straightforward)

Any comments are suggestion would be appreciated.

Truth,
James Curran
MVP (for .um. VC++)

推荐答案

" James Curran" < JA ********* @ mvps.org>写道:
"James Curran" <Ja*********@mvps.org> wrote:
[...]
foreach语句允许迭代集合的所有元素。但是,通常系列的第一个或最后一个元素必须以与集合中其他元素不同的方式处理。
[...]
目前,foreach构造主要是syntactic
糖使用IEnumerator进行一段时间的循环
[...]


我会说你的建议看起来很令人不愉快的语法糖。在

本身。


''foreach''和索引''for''几乎可以互换。在这些特殊情况下使用''for''

循环并检查特定的迭代几乎不是一个繁琐的任务,当然不够,所以要在一个新的关键字中使用一个新的关键字。

语言。如果它是你想要区别对待的第二次*迭代会怎么样?

如果有一个''第二''关键字,或者某种''foreach ......

case''构造?

任何意见建议都会受到赞赏。
[...]
The foreach statement allows iterating over all the
elements of a collection. However, often the first
or last element of the collection must be handled
differently than the others in the collection.
[...]
Presently, a foreach construct is largely "syntactic
sugar" around a while loop using an IEnumerator
[...]
I''d say that your proposal is rather unpleasant-looking "syntactic sugar" in
itself.

''foreach'' and indexed ''for'' are pretty much interchangeable. Using a ''for''
loop in those special cases and checking for specific iterations is hardly a
cumbersome task, certainly not enough so to merit a new keyword in the
language. What if it''s the *second* iteration you want to treat differently;
should there be a ''second'' keyword as well, or some kind of ''foreach ...
case'' construct?
Any comments are suggestion would be appreciated.




我只是没想到这是必要的。


我有点受到这样一个事实的影响,即当我想要使用''foreach''时我会想要

来迭代所有的元素,但不关心他们出现的顺序

in。当我想要一个明确的顺序,我用''为''。 (IEnumerator

是否应按任何特定顺序归还?我不知道。)


P.



I just don''t think it''s necessary.

I''m somewhat influenced by the fact that I tend to use ''foreach'' when I want
to iterate over all of the elements but don''t care which order they come up
in. When I want things in a definite order, I use ''for''. (Is IEnumerator
supposed to return things in any particular order? I don''t know.)

P.




" Paul E Collins" <音响****************** @ CL4.org>在消息中写道

新闻:c4 ********** @ hercules.btinternet.com ...

"Paul E Collins" <fi******************@CL4.org> wrote in message
news:c4**********@hercules.btinternet.com...
''foreach''并编入索引''因为''几乎可以互换。


实际上他们不是。 foreach适用于实现

IEnumerable的每个类,它很小且易于实现。索引需要

实现IList,这更复杂。许多集合

实现不适合索引(任何使用

树而不是幕后数组的东西)。在MSDN中查看他们的解释

页面。在框架中,两倍多的类实现

IEnumerable为IList。
''foreach'' and indexed ''for'' are pretty much interchangeable.
Actually they aren''t. foreach works for every class that implements
IEnumerable, which is small and easy to implement. Indexing requires
implementing IList which is more complicated. Many collection
implementations don''t lend themselves well to indexing (anything which using
a tree instead of an array behind the scenes). Check out their desciption
pages in the MSDN. In the framework over twice as many classes implement
IEnumerable as IList.
我受某种程度的影响当我
I''m somewhat influenced by the fact that I tend to use ''foreach'' when I



想要

迭代所有元素但我不在乎他们出现了哪个订单

in<<


只是因为集合中的物品没有特定的订单,

并不意味着在处理时,第一个和最后一个不需要以不同的方式处理
。在我添加逗号的例子中,通常它只是

这个项目是第一次处理的事实足以需要特殊的

处理。

如果你想要区别对待*第二次*迭代会怎么样?
如果有一个''第二''关键字,或者某种''foreach ...... <案例''构建?


want
to iterate over all of the elements but don''t care which order they come up
in <<

Just because there is no particular order to the items in the collection,
does not mean when being processed, the first and last do not need to be
processed differently. As in my example of adding the comma, often it''s just
the fact that this item is the first processed is enough to require special
processing.
What if it''s the *second* iteration you want to treat differently;
should there be a ''second'' keyword as well, or some kind of ''foreach ...
case'' construct?




编号需要采用不同方式处理第一个或最后一个项目是相当普遍的。

需要治疗除了第一个或最后一个项目之外的其他项目很多

稀有。另外,没有简单的实现方式来处理中间项目

不同。


我想基本的问题是什么是一个foreach在

语言无论如何都可以用for或while语句替换它?

如果你看到用语言有优势,你应该看到

的优点。



No. Needing to treat the first or last item differently is fairly common.
Needing to treat an item besides the first or last differently is much
rarer. Also, there is no simple implementation for treating a middle item
differently.

I guess the basic question is what is the point of having a foreach in the
language anyway, when it can always be replaced by a for or while statement?
If you see an advantage in having it in the language, you should see the
advantage of this.




" James Curran" < JA ********* @ mvps.org>在留言中写道

新闻:OE ************** @ TK2MSFTNGP12.phx.gbl ...

"James Curran" <Ja*********@mvps.org> wrote in message
news:OE**************@TK2MSFTNGP12.phx.gbl...
我想要为C#
语言的新功能提出以下建议。我与微软的C#团队没有关系。我在这里发布
它来收集输入以改进它,在开源中。方式,以及
尝试建立一个支持的地面膨胀,以说服微软的人们添加它。
提案:第一: "最后:" foreach中的部分块

问题:
foreach语句允许迭代
集合的所有元素。但是,通常集合的第一个或最后一个元素的处理方式必须与集合中的其他元素不同。例如,如果我们生成了一个要显示的项目列表,我们需要在除了最后一项之外的每个项目之后使用逗号。在这些情况下,不能使用foreach,并且
可以使用的替代品通常是丑陋的,并且通常效率低于foreach。需要一个符合C#概念的优雅解决方案。


好​​的,我同意这是一个没有优雅解决方案的情况。我已经看到了一些其他解决方案可以帮助解决这个问题(隐式索引和

长度变量,我自己带有扩展IEnumerator的命名枚举器)但是

,因为你说明他们不容易或不可能修改基础

类..建议:
我建议添加四个新关键字(仅在foreach块内可用)
将编译器指向我们的确切意图。 "第一:" "最后:" 其他:"
所有:"

虽然这很有意思,但我必须同意保罗说它没有抓住

边缘情况,这是需要解决的问题。我会继续

想一想,看看我能想到什么来管理这样的事情。在这里有

的潜在效用(虽然它可能不是主流编译器的功能)并且至少值得探索。

缺点:
它需要四个关键字,虽然这可以减少到三个
(消除all:),并且它们每个都会对上下文非常敏感,所以

与用户定义的标识符冲突的可能性不大。


都可能是隐含的,或者你可以默认搭载。

另外使用案例< label> :(或另一个词)和对待一个foreach

就像一个开关可以让你修改语法而不会破坏现有代码。两个词的关键词在语法上是可能的(在C#2.0中证明了

的收益率),而拥有两个词的标识符是不合法的。
实施:
目前, foreach构造主要是语法糖。使用IEnumerator循环一段时间,使得代码写成
foreach(int i in arry)
{
Console.WriteLine(i);
}

编译就像编写它一样:
IEnumerator n = arry.GetEnumerator();
while(n.MoveNext())
{
int i =(int)n.Current;
Console.WriteLine(i);
}
同样,使用这些块的代码也可以直接翻译:
foreach(int in arry)
{
首先:
Console.WriteLine(" {0} - first",i);
其他:
Console.WriteLine(i);
}
将编译为:
IEnumerator n = arry.GetEnumerator();
if(n.MoveNext())
{i /(int)n.Current;
Console.WriteLine(" {0} - first",i);
while(n.MoveNext ())
{
i =(int)n。当前;
Console.WriteLine(i);
}
}
(内部表示) last:块的含义更多一些d,

仍然基本上是直截了当的)

任何意见建议将不胜感激。


我认为对于这样的功能,探索用法的最佳方式是实际使用它们。
。你有没有考虑修改单声道或转子并添加

这个功能(或它的排列)?如果你发布它,它会给你和其他人,有机会看到它在真实代码中是如何工作的。
真相,
James Curran
MVP (对于.um.VC ++)
I''d like to make the following proposal for a new feature for the C#
language. I have no connection with the C# team at Microsoft. I''m
posting
it here to gather input to refine it, in an "open Source" manner, and in
an
attempt to build a ground-swell of support to convince the folks at
Microsoft to add it.
Proposal: "first:" "last:" sections in a "foreach" block

The problem:
The foreach statement allows iterating over all the elements of a
collection. However, often the first or last element of the collection
must
be handled differently than the others in the collection. For example, if
we were generating a list of items for display, we''d want a comma after
every item except the last. In these cases, foreach cannot be used, and
the
alternates which can be used are generally ugly and often less efficient
than foreach. An elegant solution keeping with the concept of C# is
needed.

Ok, I agree that this is a situation where no elegant solution exists. I''ve
seen a few other solutions that would help with this(implicit index and
length variables, my own named enumerators with an extended IEnumerator) but
as you illustrate they aren''t easy or possible without modifying base
classes.. The proposal:
I suggest adding four new keywords (only available inside foreach block)
to
direct the compiler to our exact intentions. "first:" "last:" "other:"
"all:"
While this is interesting, I have to agree with Paul that it doesn''t catch
edge cases, which is something that needs to be addressed. I''ll continue to
think about it and see what I can think of to manage such. There is
potential utility in this(although it may not be a feature that would make
the mainstream compiler) and it is atleast worth exploring.
The disadvantages:
It requires four keywords, although this could be reduced to three
(eliminating "all:") and, they would each be very context sensitive, so
the
conflicts with user-defined identifiers is unlikely.
all could either be implicit and\or you could piggy back with default.
Additionally using case <label>:(or another word) and treating a foreach
like a switch would allow you to modify the syntax without disrupting
existing code. Two word keywords are syntactically possible(as evidenced
with yield in C# 2.0) while it isn''t legal to have a two word identifier.
Implementation:
Presently, a foreach construct is largely "syntactic sugar" around a while
loop using an IEnumerator, such that code written as
foreach (int i in arry)
{
Console.WriteLine(i);
}

Would be compiled much as if it were written:
IEnumerator n = arry.GetEnumerator();
while(n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine(i);
}

Similarly, code using these blocks would also have a direct translation:
foreach (int i in arry)
{
First:
Console.WriteLine("{0} - first", i);
Others:
Console.WriteLine(i);
}

Would be compiled as:
IEnumerator n = arry.GetEnumerator();
if (n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine("{0}-- first ", i);
while(n.MoveNext())
{
i = (int) n.Current;
Console.WriteLine(i);
}
}
(The internal representation of a "last:" block is a bit more involved,
but
still basically straightforward)

Any comments are suggestion would be appreciated.
I think that for features like this the best way to explore the usage is to
actually use them. Have you considered modifying mono or rotor and adding
the feature(or permutations of it)? It will give you, and others if you
release it, a chance to see how it would really work in real code.
Truth,
James Curran
MVP (for .um. VC++)



这篇关于[功能请求]“首先:” &QUOT;最后:&QUOT; “foreach”中的部分块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆