C# 每个循环的lambda表达式

C# 每个循环的lambda表达式,c#,.net,lambda,C#,.net,Lambda,我有以下代码 int someCount = 0; for ( int i =0 ; i < intarr.Length;i++ ) { if ( intarr[i] % 2 == 0 ) { someCount++; continue; } // Some other logic for those not satisfying the condition } int someCount=0; 对于(int i=0;i失败; 返回

我有以下代码

int someCount = 0;

for ( int i =0 ; i < intarr.Length;i++ )
{
   if ( intarr[i] % 2 == 0 )
   { 
       someCount++;
       continue;
   }
   // Some other logic for those not satisfying the condition
}
int someCount=0;
对于(int i=0;i
是否可以使用Array.Where或Array.SkiplWhile中的任何一个来实现相同的功能

foreach(int i in intarr.where(<<condtion>> + increment for failures) )
{
      // Some other logic for those not satisfying the condition    
}
foreach(整数中的整数i,其中(+故障增量))
{
//对于那些不满足条件的人,还有一些其他的逻辑
}
使用LINQ:

int someCount = intarr.Count(val => val % 2 == 0);
使用LINQ:

int someCount = intarr.Count(val => val % 2 == 0);

对于短语句,我当然更喜欢@nneonneo的方法(它使用显式lambda),但如果您想构建更复杂的查询,可以使用:

显然,当查询可以用单个lambda表达式表示时,这可能是一个糟糕的选择,但我发现它在编写更大的查询时很有用


更多示例:

我当然更喜欢@nneonneo的短语句方式(它使用显式lambda),但如果您想构建更复杂的查询,可以使用:

显然,当查询可以用单个lambda表达式表示时,这可能是一个糟糕的选择,但我发现它在编写更大的查询时很有用

更多示例:

没有什么(很多)可以阻止您在计算失败的地方滚动自己的
“没什么”,因为lambda和带有
产生返回
语句的方法都不允许引用out/ref参数,,所以带有以下签名的所需扩展将不起作用

// dead-end/bad signature, do not attempt
IEnumerable<T> Where(
    this IEnumerable<T> self,
    Func<T,bool> predicate,
    out int failures)
//死胡同/签名错误,请勿尝试
我在哪里(
这个不可数的自我,
Func谓词,
out int失败)
但是,我们可以为故障计数声明一个局部变量,并返回一个可以获取故障计数的
Func
,并且局部变量完全可以从lambdas引用。因此,这里有一个可能的(经过测试的)实现:

public static class EnumerableExtensions
{
    public static IEnumerable<T> Where<T>(
        this IEnumerable<T> self,
        Func<T,bool> predicate,
        out Func<int> getFailureCount)
    {
        if (self == null) throw new ArgumentNullException("self");
        if (predicate == null) throw new ArgumentNullException("predicate");

        int failures = 0;

        getFailureCount = () => failures;

        return self.Where(i =>
            {
                bool res = predicate(i);
                if (!res)
                {
                    ++failures;
                }
                return res;
            });
    }
}
公共静态类EnumerableExtensions
{
公共静态IEnumerable在哪里(
这个不可数的自我,
Func谓词,
输出功能(getFailureCount)
{
如果(self==null)抛出新的ArgumentNullException(“self”);
如果(谓词==null)抛出新的ArgumentNullException(“谓词”);
int=0;
getFailureCount=()=>失败;
返回self.Where(i=>
{
bool-res=谓词(i);
如果(!res)
{
++失败;
}
返回res;
});
}
}
…下面是一些测试代码:

Func<int> getFailureCount;
int[] items = { 0, 1, 2, 3, 4 };
foreach(int i in items.Where(i => i % 2 == 0, out getFailureCount))
{
    Console.WriteLine(i);
}
Console.WriteLine("Failures = " + getFailureCount());
Func-getFailureCount;
int[]项={0,1,2,3,4};
foreach(items.Where(i=>i%2==0,out getFailureCount)中的int i)
{
控制台写入线(i);
}
Console.WriteLine(“Failures=“+getFailureCount());
上述测试在运行输出时:

0
2
4
故障=2

我觉得有几个警告是有义务警告的。由于您可能会在没有遍历整个
IEnumerable
的情况下过早地跳出循环,因此故障计数将只反映遇到的故障,而不是@nneonneo解决方案中的故障总数(我更喜欢),如果LINQ的
其中
扩展的实现以每项调用谓词不止一次的方式更改,那么失败计数将是不正确的。还有一点值得注意的是,在循环体中,您应该能够调用getFailureCount函数来获取当前运行的失败计数

我提出这个解决方案是为了表明我们并没有被现有的预包装解决方案所束缚。语言和框架为我们提供了许多机会来扩展它以满足我们的需要。

没有什么(很大)可以阻止您在计算失败的地方滚动自己的
“没什么”,因为lambda和带有
产生返回
语句的方法都不允许引用out/ref参数,,所以带有以下签名的所需扩展将不起作用

// dead-end/bad signature, do not attempt
IEnumerable<T> Where(
    this IEnumerable<T> self,
    Func<T,bool> predicate,
    out int failures)
//死胡同/签名错误,请勿尝试
我在哪里(
这个不可数的自我,
Func谓词,
out int失败)
但是,我们可以为故障计数声明一个局部变量,并返回一个可以获取故障计数的
Func
,并且局部变量完全可以从lambdas引用。因此,这里有一个可能的(经过测试的)实现:

public static class EnumerableExtensions
{
    public static IEnumerable<T> Where<T>(
        this IEnumerable<T> self,
        Func<T,bool> predicate,
        out Func<int> getFailureCount)
    {
        if (self == null) throw new ArgumentNullException("self");
        if (predicate == null) throw new ArgumentNullException("predicate");

        int failures = 0;

        getFailureCount = () => failures;

        return self.Where(i =>
            {
                bool res = predicate(i);
                if (!res)
                {
                    ++failures;
                }
                return res;
            });
    }
}
公共静态类EnumerableExtensions
{
公共静态IEnumerable在哪里(
这个不可数的自我,
Func谓词,
输出功能(getFailureCount)
{
如果(self==null)抛出新的ArgumentNullException(“self”);
如果(谓词==null)抛出新的ArgumentNullException(“谓词”);
int=0;
getFailureCount=()=>失败;
返回self.Where(i=>
{
bool-res=谓词(i);
如果(!res)
{
++失败;
}
返回res;
});
}
}
…下面是一些测试代码:

Func<int> getFailureCount;
int[] items = { 0, 1, 2, 3, 4 };
foreach(int i in items.Where(i => i % 2 == 0, out getFailureCount))
{
    Console.WriteLine(i);
}
Console.WriteLine("Failures = " + getFailureCount());
Func-getFailureCount;
int[]项={0,1,2,3,4};
foreach(items.Where(i=>i%2==0,out getFailureCount)中的int i)
{
控制台写入线(i);
}
Console.WriteLine(“Failures=“+getFailureCount());
上述测试在运行输出时:

0
2
4
故障=2

我觉得有几个警告是有义务警告的。由于您可以在没有遍历整个
IEnumerable
的情况下过早地跳出循环,因此故障计数将只反映遇到的故障,而不是@nneonneo的解决方案(我更喜欢)中的故障总数。此外,如果LINQ的
Where
扩展的实现以c