8

我有多个验证布尔属性,可能需要或不需要。如果需要它们,则需要对其进行检查以进行验证。因此,我必须构建多个 if 语句来处理每个属性。我的问题是是否有更好的方法来维护这一点,而不必为每个新属性编写 if 。

public class ProductionNavbarViewModel
{
    public bool IsProductionActive { get; set; }
    public bool ValidatedComponents { get; set; }
    public bool ValidatedGeometries { get; set; }
    public bool ValidatedPokayokes { get; set; }
    public bool ValidatedTechnicalFile { get; set; }
    public bool ValidatedStandardOperationSheet { get; set; }
    public bool ValidatedOperationMethod { get; set; }
    public bool IsComponentsRequired { get; set; }
    public bool IsGeometriesRequired { get; set; }
    public bool IsPokayokesRequired { get; set; }
    public bool IsTechnicalFileRequired { get; set; }
    public bool IsStandardOperationSheetRequired { get; set; }
    public bool IsOperationMethodRequired { get; set; }


    public bool IsProductionReadyToStart()
    {
        if (IsComponentsRequired)
        {
            return ValidatedComponents;
        }

        if (IsComponentsRequired && IsGeometriesRequired)
        {
            return ValidatedComponents && ValidatedGeometries;
        }

        if (IsComponentsRequired && IsGeometriesRequired && IsPokayokesRequired)
        {
            return ValidatedComponents && ValidatedGeometries && ValidatedPokayokes;
        }

        if (IsComponentsRequired && IsGeometriesRequired && IsPokayokesRequired && IsTechnicalFileRequired)
        {
            return ValidatedComponents && ValidatedGeometries && ValidatedPokayokes && ValidatedTechnicalFile;
        }

        if (IsComponentsRequired && IsGeometriesRequired && IsPokayokesRequired && IsTechnicalFileRequired && ValidatedStandardOperationSheet)
        {
            return ValidatedComponents && ValidatedGeometries && ValidatedPokayokes && ValidatedTechnicalFile && ValidatedStandardOperationSheet;
        }

        if (IsComponentsRequired && IsGeometriesRequired && IsPokayokesRequired && IsTechnicalFileRequired && IsStandardOperationSheetRequired && IsOperationMethodRequired)
        {
            return ValidatedComponents && ValidatedGeometries && ValidatedPokayokes && ValidatedTechnicalFile && ValidatedStandardOperationSheet && ValidatedOperationMethod;
        }

        return false;
    }
}

编辑

编写此代码时出现问题。目的是验证所有选项,它们必须是必要的,如果只有一个属性满足条件,则无法返回。

谢谢大家,我会在评论中尝试一些建议的方法,然后我会发布结果

更新

我现在提供了一个简短的版本,并且根据每个人的评论更具可读性,直到我可以尝试每种方法。编辑以根据@Alexander Powolozki 的回答组合所有表达式。

    public bool IsProductionReadyToStart()
    {
        bool isValid = true;

        isValid &= !IsComponentsRequired || ValidatedComponents;
        isValid &= !IsGeometriesRequired || ValidatedGeometries;
        isValid &= !IsPokayokesRequired || ValidatedComponents;
        isValid &= !IsTechnicalFileRequired || ValidatedTechnicalFile;
        isValid &= !IsStandardOperationSheetRequired || ValidatedStandardOperationSheet;
        isValid &= !IsOperationMethodRequired || ValidatedOperationMethod;            

        return isValid;
    }
4

6 回答 6

7

该方法的正确实现应该如下所示:

public bool IsProductionReadyToStart()
{
    bool isValid = true;

    isValid &= !IsComponentsRequired || ValidatedComponents;
    isValid &= !IsGeometriesRequired || ValidatedGeometries;
    isValid &= !IsPokayokesRequired || ValidatedPokayokes;
    isValid &= !IsTechnicalFileRequired || ValidatedTechnicalFile;
    isValid &= !IsStandardOperationSheetRequired || ValidatedStandardOperationSheet;
    isValid &= !IsOperationMethodRequired || ValidatedOperationMethod;            

    return isValid;
}

当不使用 &= 时,您会删除所有先前检查的结果,而不是合并它们。

于 2020-05-27T09:06:10.627 回答
7

它看起来像一个集合

public class Validation
{
    public bool Required { get; set; }
    public bool IsValid { get; set; }
}

var validations = new[]
{
    new Validation { Required = true, IsValid = true },
    new Validation { Required = false, IsValid = true },
    new Validation { Required = true, IsValid = false },
};

// return true only when all required validations are valid
public bool IsProductionReadyToStart()
{
    return _validations.Where(v => v.Required).All(v => v.IsValid);
}
于 2020-05-27T09:06:25.713 回答
5

我会去:

if (IsComponentsRequired && !ValidateComponents) return false;
if (IsGeometriesRequired && !ValidatedGeometries) return false;
...
return true;

这更像是一个清单。

于 2020-05-27T09:04:07.323 回答
5

您可以将您的条件累积到ValueTuple集合中,然后将它们一起检查

var conditions = new[]
{
    (IsComponentsRequired, ValidatedComponents),
    (IsGeometriesRequired, ValidatedGeometries),
    (IsPokayokesRequired, ValidatedPokayokes)
};

return conditions.Where(c => c.Item1).All(c => c.Item2);

您还可以使用命名元组语法来提高可读性

var conditions = new (bool isRequired, bool validated)[]
{
    (IsComponentsRequired, ValidatedComponents),
    (IsGeometriesRequired, ValidatedGeometries),
    (IsPokayokesRequired, ValidatedPokayokes)
};

return conditions.Where(c => c.isRequired).All(c => c.validated);
于 2020-05-27T09:14:15.793 回答
3

我喜欢使用的是&=,它看起来很干净,但缺点是不是每个人都熟悉这种方法。


bool result = true;

result &= !IsComponentsRequired || IsComponentsRequired && ValidatedComponents;
result &= !IsGeometriesRequired|| IsGeometriesRequired && ValidatedGeometries;
//...etc
return result;

此代码的功能与以下内容相同:

result = result && (!IsComponentsRequired || IsComponentsRequired && ValidatedComponents);
//...etc

但我认为按位运算看起来更干净。

于 2020-05-27T09:19:17.977 回答
1

我认为您真正想要的是:

return 
    (IsComponentsRequired && ValidatedComponents || IsComponentsRequired == false) &&
    (IsGeometriesRequired && ValidatedGeometries) || IsGeometriesRequired == false) &&
    (IsPokayokesRequired && ValidatedPokayokes || IsPokayokesRequired == false ) &&
    (IsTechnicalFileRequired && ValidatedTechnicalFile ||  IsTechnicalFileRequired == false) &&
    (IsStandardOperationSheetRequired && ValidatedStandardOperationSheet || IsTechnicalFileRequired == false) &&
    (IsOperationMethodRequired && ValidatedOperationMethod || IsOperationMethodRequired == false )

这可以使用反射来实现,因此在添加更多属性时无需更改代码:

public class ProductionNavbarViewModel
{
    public bool IsProductionActive { get; set; }
    public bool ValidatedComponents { get; set; }
    public bool ValidatedGeometries { get; set; }
    public bool ValidatedPokayokes { get; set; }
    public bool ValidatedTechnicalFile { get; set; }
    public bool ValidatedStandardOperationSheet { get; set; }
    public bool ValidatedOperationMethod { get; set; }
    public bool IsComponentsRequired { get; set; }
    public bool IsGeometriesRequired { get; set; }
    public bool IsPokayokesRequired { get; set; }
    public bool IsTechnicalFileRequired { get; set; }
    public bool IsStandardOperationSheetRequired { get; set; }
    public bool IsOperationMethodRequired { get; set; }


    public bool IsProductionReadyToStart()
    {
        var validatedProps = this.GetType().GetProperties().Where(x => x.Name.StartsWith("Validated"));
        foreach (var validatedProp in validatedProps)
        {
            var concept = validatedProp.Name.Substring(9);
            var isRequiredProp = this.GetType().GetProperty("Is" + concept + "Required");
            var isRequired = (bool)isRequiredProp.GetValue(this);
            if (isRequired)
            {
                var isValid = (bool)validatedProp.GetValue(this);
                if (isValid == false) return false;
            }
        }
        return true;
    }
}
于 2020-05-27T09:19:55.960 回答