Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带LINQ的条件接收_C#_Enumeration_Yield Return - Fatal编程技术网

C# 带LINQ的条件接收

C# 带LINQ的条件接收,c#,enumeration,yield-return,C#,Enumeration,Yield Return,我有两个验证器,用于验证IDeliveryObject,从概念上讲,它可以描述为一个包含多行的文件。那部分很好用 IEnumerable<IDeliveryValidator> _validators; // Populated in ctor. Usually around 20 different validators. private IEnumerable<IValidationResult> Validate(IDeliveryObject deliveryO

我有两个验证器,用于验证
IDeliveryObject
,从概念上讲,它可以描述为一个包含多行的文件。那部分很好用

IEnumerable<IDeliveryValidator> _validators; // Populated in ctor. Usually around 20 different validators.

private IEnumerable<IValidationResult> Validate(IDeliveryObject deliveryObject)
{
    var validationErrors = new List<IValidationResult>();
    int maxNumberOfErrors = 10;
    foreach (IDeliveryValidator deliveryValidator in _validators)
    {
        IEnumerable<IValidationResult> results = deliveryValidator.Validate(deliveryObject).Take(maxNumberOfErrors);
        validationErrors.AddRange(results);
        if (validationErrors.Count >= maxNumberOfErrors )
        {
            return validationErrors.Take(maxNumberOfErrors).ToList();
        }
    }
    return validationErrors;
}
多亏了
Take(maxNumberOfErrors)
yield
,每个验证器只返回10个验证结果,这过去是可以的。但现在我需要处理“软验证结果”,这是同一种验证结果,但它不应包含在生成的结果数量中。这是一种警告,通过在
IValidationResult
中设置
IsSoftError
来定义。验证器可以产生“软验证结果”和“常规验证结果”

我想要的是获得x个验证结果+无限软验证结果,这样所有
IValidationResults
IsSoftError==true
都将包括在集合中,但不包括在计数中。我知道这听起来很奇怪,但概念是在x个错误之后不需要继续验证文件,但是验证可以返回无限的“警告”

枚举不能多次枚举,这一点非常重要,因为它占用大量CPU。下面是我要更改的代码

private IEnumerable<IValidationResult> Validate(IDeliveryObject deliveryObject)
{
    var validationErrors = new List<IValidationResult>();
    int maxNumberOfErrors = 10;
    foreach (IDeliveryValidator deliveryValidator in _validators)
    {
       // Here I want results to contain MAX 10 regular validation results, but unlimited soft validation results
        IEnumerable<IValidationResult> results = deliveryValidator.Validate(deliveryObject).Take(maxNumberOfErrors);
        validationErrors.AddRange(results);
        if (validationErrors.Count(x => !x.IsSoftError) >= maxNumberOfErrors)
        {
            return validationErrors.Take(maxNumberOfErrors).ToList();
        }
    }
    return validationErrors;
}
private IEnumerable验证(IDeliveryObject deliveryObject)
{
var validationErrors=新列表();
int maxNumberOfErrors=10;
foreach(IDeliveryValidator deliveryValidator in_validators)
{
//在这里,我希望结果包含最多10个常规验证结果,但不限软验证结果
IEnumerable results=deliveryValidator.Validate(deliveryObject.Take)(maxNumberOfErrors);
validationErrors.AddRange(结果);
if(validationErrors.Count(x=>!x.IsSoftError)>=maxNumberOfErrors)
{
返回validationErrors.Take(maxNumberOfErrors.ToList();
}
}
返回验证错误;
}
编辑:
当我有10个“硬”错误时,我想完全停止循环。这里的主要问题是循环在发生10个“软”错误时不会停止。

如果您想在10个“硬”错误后完全停止,您可以尝试以下方法:

//Go through all the items and sort them into Soft and NotSoft
//But ultimately these are in memory constructs...so this is fast.
var foo = Validate(delivery).ToLookup(x => x.IsSoftError);
var soft = foo[true];
var hard = foo[false].Take(10);
var result = Enumerable.Concat(soft, hard);
int count = 0;
IEnumerable<IValidationResult> results = deliveryValidator.Validate(deliveryObject)
    .TakeWhile(error => error.IsSoftError || count++ < maxNumberOfErrors);
int count=0;
IEnumerable results=deliveryValidator.Validate(deliveryObject)
.TakeWhile(error=>error.IsSoftError | | count++

当遇到第11个硬错误时,此操作将停止。

是否希望每个验证器最多有10个非软错误?还是总体?如果你想得到所有的软错误。然后必须枚举到最后,即使达到10个非软错误。这意味着您应该只在最后过滤最终结果。在得到100个非软错误后,可能会出现一些软错误。实际上,总体而言。但我现在的解决方案仍然有效,我会跟踪总数,并为每个验证器添加10个以上的错误。如果是10+10,这并不重要。我认为他希望在出现10个“硬”错误时停止评估。@ManuelSchweigert,但它必须继续获得软错误。@ManuelSchweigert还要求在Linq中找到解决方案,这将需要这种方法,鉴于Linq是基于Monad函数式编程的,很抱歉说得含糊不清。我想在10个“硬”错误之后完全停止。当发生10个硬错误时,我不需要继续获取软错误。看起来很有希望。我以前有一段时间没用过。我会试试,然后再打给你……结果证明这正是我想要的。条件Take()。:)我不想发布这个问题,因为这感觉像是一个愚蠢/无法解决的问题,但现在我很高兴我发布了。谢谢你,曼纽尔。
//Go through all the items and sort them into Soft and NotSoft
//But ultimately these are in memory constructs...so this is fast.
var foo = Validate(delivery).ToLookup(x => x.IsSoftError);
var soft = foo[true];
var hard = foo[false].Take(10);
var result = Enumerable.Concat(soft, hard);
int count = 0;
IEnumerable<IValidationResult> results = deliveryValidator.Validate(deliveryObject)
    .TakeWhile(error => error.IsSoftError || count++ < maxNumberOfErrors);