Альтернативный способ записать доходность

Есть ли способ избавиться от .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 ответа

Решение

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");
}

Я не так знаком с 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 в ValidationResultIfRequired а также Validate в:

ValidationResult validationResult;

// ...

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

validationResult = ValidationResultIfRequired(entity.Profile.LastName, "Last Name");
// etc
Другие вопросы по тегам