C# 什么';这是最好的循环方式
对不起,标题不好。 下面的代码本身非常简单且不言自明。我基本上使用一个项目的索引,如果它存在的话。我不喜欢的是下面的代码实际上做了两次相同的事情(someList.IndexOf) 我想知道是否有更好的办法。我想在循环中再次使用值(请原谅我缺乏术语),就像在for循环中使用“I”一样C# 什么';这是最好的循环方式,c#,for-loop,while-loop,C#,For Loop,While Loop,对不起,标题不好。 下面的代码本身非常简单且不言自明。我基本上使用一个项目的索引,如果它存在的话。我不喜欢的是下面的代码实际上做了两次相同的事情(someList.IndexOf) 我想知道是否有更好的办法。我想在循环中再次使用值(请原谅我缺乏术语),就像在for循环中使用“I”一样 while(value) { //use the value here} 你基本上是在做一些事情,直到离开清单。因此,您也可以使用: using System.Linq; var something = som
while(value) { //use the value here}
你基本上是在做一些事情,直到离开清单。因此,您也可以使用:
using System.Linq;
var something = someList[7]; // get your item from someList
while( !someList.Any( elem => elem == something))
{
// if this is practicable depends on your "things" to do to something
}
您可能希望尝试为循环实现更可读的
,而不是,同时
实现一个:
for(int index = someList.IndexOf(something);
index >= 0;
index = someList.IndexOf(something)) {
...
}
请注意,循环声明中没有开销(计算IndexOf
两次)和所有内容,因此您可以在while循环中设置和测试,比如说,继续
,而无需任何其他代码
while((someIndex = someList.IndexOf(something)) != -1){
}
还不完全清楚您所说的更好是什么意思,尽管我只能假设您的意思是在“可维护性”和“表达能力”之间达成某种交集。然而,即使这种形式的清晰,你也需要给我们一个真实世界问题的描述,以便我们能最好地帮助你。该网站通常不适合此类问题。因此,我投票决定结束
在考虑这两个条件时,重复表达式index=someList.IndexOf(something)
是不可接受的(请注意,似乎只是这样)。因此,为
循环选择平凡的,可能是不合适的(同样,也只是轻微)
您可以将分配提升到循环控件中,但这可能会影响可维护性,因为所需的额外嵌套括号将使代码看起来不那么透明/立即易于理解
在过程编程领域,我的建议是从通常放置循环控件的位置(在控制表达式中)提取循环控件,并将其嵌入到循环中。例如:
for (;;) {
int index = someList.IndexOf(something);
if (index == -1) {
break;
}
// XXX: Make use of `index` here.
}
这符合两个标准;它不会不必要地重复代码,而且它是惯用的,易于阅读和理解。当然,C语言引入了许多工具,包括一些使循环内化的功能方面,引入了更多的选项来考虑这样一个模糊的问题。例如,您可以使用Aggregate
方法生成一个新列表,并将其分配到旧列表的顶部,如下所示:
someList = someList.Aggregate(new List(T), (list, item) => {
if (item != something) { list.Add(item); }
else { /* XXX: Do something else */ }
return list;
});
这不可能是你所有选择的详尽答案由于您没有向我们提供关于更广泛的情况的任何信息(您试图解决的是什么现实生活问题),这可能是一个,因此在定义“现实世界问题”时,提出“您认为您需要什么”的问题可能是有好处的。只是为了提出另一个可能的解决方案。您可以添加一个扩展方法,使其更具可读性,而不必在循环本身中使用-1
幻数
public static class ListExtensions
{
public static bool TryGetIndexOf<T>(this IList<T> source, T item, out int index)
{
if(source == null) throw new ArgumentNullException(nameof(source));
index = source.IndexOf(item);
return index != -1;
}
}
公共静态类ListExtensions
{
公共静态bool TryGetIndexOf(此IList源、T项、out int索引)
{
如果(source==null)抛出新的ArgumentNullException(nameof(source));
索引=来源。索引(项目);
返回索引!=-1;
}
}
然后您的循环变成:
List<int> someList = new List<int> { 5, 10, 15, 20 };
int something = 5;
while (someList.TryGetIndexOf(something, out var idx))
{
something += 5;
}
List-someList=新列表{5,10,15,20};
int=5;
while(someList.TryGetIndexOf(something,out var idx))
{
某物+=5;
}
当然可以将它存储在某个地方(变量)。什么是somelist?什么东西?你想干什么?还有什么东西会改变?你能解释一下吗?我其实在想更优雅的方法,比如在while括号中指定变量,用一行代码。我想它不存在。感谢所有发表评论的人。@Mert,您可以在此期间分配任务。请参阅下面我的答案。这有助于减少冗余代码,但代价是添加括号,以及。。。它已经开始变得有点像口齿不清了。不过还不错,我不知道,泰。如果我们不仅能赋值,还能识别while括号中的变量,那就太好了。“开始看起来有点像Lisp了。”/shubder这么认为?我经常使用这种模式,通常是从文件中读取。e、 例如,while((line=stream.ReadLine())!=null).
YMMV。此外,大多数人在维护过程中通常会在控制语句之外的任何地方看到这种副作用。例如,您可以在(stream.Peek()>=0){string line=stream.ReadLine();…}
时编写,您的里程变化可能会小得多。作为一个额外的好处,您的变量声明通过这种方式变得更加局部……好吧,微软也在他们的文章中专门介绍了我的例子。所以,我不认为这是一个疯狂的做法。但正如我所说:)所以这不会计算两次,即使我们将它设置两次(index=someList.IndexOf())。还有泰迪。奇怪的是,我在问之前觉得这个问题很愚蠢,但我还是学到了一些新东西。@Mert这里确实没有计算开销。但是,如果有人决定someList.IndexOf(something)
需要更改,因为他们需要更改两次而不是一次。另一个不错的选择是,沿着这个方向,就是编写一个一次处理一个元素的函数,然后编写一个简单的循环来重复调用该函数。我奇怪地喜欢这个(你的答案),因为它的用法类似于type.TryParse
,并且引入了引用参数。很好地将一个模糊的问题转化为一个机会,教给某人一些C#中相对未知的细微差别:)你是否意识到这是for
循环的一种扩展形式?@Sebivor目的是用尽可能接近问题的语法回答。公认的答案只是一个简单的问题
someList = someList.Aggregate(new List(T), (list, item) => {
if (item != something) { list.Add(item); }
else { /* XXX: Do something else */ }
return list;
});
public static class ListExtensions
{
public static bool TryGetIndexOf<T>(this IList<T> source, T item, out int index)
{
if(source == null) throw new ArgumentNullException(nameof(source));
index = source.IndexOf(item);
return index != -1;
}
}
List<int> someList = new List<int> { 5, 10, 15, 20 };
int something = 5;
while (someList.TryGetIndexOf(something, out var idx))
{
something += 5;
}