写作收益的另类方式

时间:2012-01-11 01:40:13

标签: c# yield yield-return yield-keyword

有没有办法通过以下设置摆脱.FirstOrDefault()。我喜欢使用yield语句,但我想将IsRequired方法压缩到我不必使用.FirstOrDefault()的位置。

PlayerValidator

protected override IEnumerable<ValidationResult> Validate(PlayerModel entity, IValidationProvider validationProvider)
        {
            yield return ValidationResultHelper.IsRequired(entity.Profile.FirstName, "First Name").FirstOrDefault();

            if (string.IsNullOrWhiteSpace(entity.Profile.LastName))
                yield return new Required("Last Name");
        }

ValidatorHelper

public IEnumerable<ValidationResult> IsRequired(string text, string name)
{
    if (string.IsNullOrWhiteSpace(text))
        yield return new Required(name);
}

2 个答案:

答案 0 :(得分:2)

foreach将是另一种选择(如果您的示例中没有验证错误,它将不会错误地返回null):

protected override IEnumerable<ValidationResult> Validate(PlayerModel entity, IValidationProvider validationProvider)
{
    foreach (var result in ValidationResultHelper.IsRequired(entity.Profile.FirstName, "First Name"))
        yield return result;
    if (string.IsNullOrWhiteSpace(entity.Profile.LastName))
        yield return new Required("Last Name");
}

答案 1 :(得分:1)

我对yield return的熟悉程度并不尽如人意,但在这种情况下,我认为您在yield return中使用IsRequired的方式是使用了错误的工具工作。我的结构会略有不同:

ValidatorHelper

// Note this function is almost unnecessary and might be better
// implemented in AddIfRequired if validation is this trivial.
public static bool IsRequired(string text)
{
    return string.IsNullOrWhiteSpace(text);
}

PlayerValidator

private static void AddIfRequired(string text, string name, List<ValidationResult> validationResults)
{
    if (ValidatorHelper.IsRequired(text))
        requiredList.Add(new Required(name));
}

protected override IEnumerable<ValidationResult> Validate(PlayerModel entity, IValidationProvider validationProvider)
{
    List<ValidationResult> validationResults = new List<ValidationResult>();

    AddIfRequired(entity.Profile.FirstName, "First Name", validationResults);
    AddIfRequired(entity.Profile.LastName, "Last Name", validationResults);
    // ...

    return validationResults;
}

如果您真的想使用yield return并保存自己创建列表并每次验证所有字段(虽然我不认为这会是性能问题),您可以将AddIfRequired变为ValidationResultIfRequiredValidate进入:

ValidationResult validationResult;

// ...

validationResult = ValidationResultIfRequired(entity.Profile.FirstName, "First Name");
if (validationResult != null)
    yield return validationResult;

validationResult = ValidationResultIfRequired(entity.Profile.LastName, "Last Name");
// etc