简体   繁体   English

我怎样才能使我的 if 语句不那么矛盾?

[英]How can I make my if statements less contradictory?

I have a points system for a password strength checker that I am working on.我有一个我正在研究的密码强度检查器的积分系统。

Currently the rules work like something this: +5 if the user entry has a lower case letter, +10 if it has a lower and upper case letter, a number or a special character,etc.目前,规则的工作方式如下:如果用户条目有小写字母,则 +5,如果用户条目有大小写字母、数字或特殊字符等,则 +10。

The problem I have ran into is that my if statements are contradictory and I was wandering if there were any alternatives I could use.我遇到的问题是我的 if 语句是矛盾的,如果有任何我可以使用的替代方案,我正在徘徊。

The statements below is me trying to get it so if they put in a certain type of character, they will gain points and it will contribute to the score, ie if it has a number, then +5 to the score.下面的陈述是我试图得到它,所以如果他们放入某种类型的角色,他们将获得积分,这将有助于得分,即如果它有一个数字,那么 +5 得分。

if (userPassword.Any(char.IsDigit))
{
    points += 5;
}

if (userPassword.Any(char.IsLower))
{
    points += 5;
}

if (userPassword.Any(char.IsUpper))
{
    points += 5;
}

if (userPassword.Any(c => specialCharacters.Contains(c)))
{
    points += 5;
}

To get rid of the contradiction, I tried to do an.all function on the statements that potentially deduct points of the user, but it seems inadequate and I don't think it is quite right for this programme.为了摆脱矛盾,我尝试在可能会扣除用户积分的陈述上做一个.all function,但似乎不够,我认为这对这个程序来说不太合适。

I am basically trying to get it to deduct points if the user is using only one type of character, ie if they only use numbers and nothing else they will lose points.如果用户只使用一种类型的字符,我基本上试图让它扣分,即如果他们只使用数字而不使用其他任何东西,他们将失去积分。

if (userPassword.All(char.IsLower) || userPassword.All(char.IsUpper)) 
{
    points -= 5;
}

if (userPassword.All(char.IsDigit)) 
{
    points -= 5;
}

if (userPassword.All(c => specialCharacters.Contains(c))) 
{
    points -= 5;
}

What would be an alternative to solve this?解决这个问题的替代方法是什么?

EDIT: Ok thank you for clarifying that there isn't anything wrong with my if statements.编辑:好的,感谢您澄清我的 if 语句没有任何问题。 I now want to add an if statement that adds 10 points if it contains an upper case, lower case, digit and special character.我现在想添加一个 if 语句,如果它包含大写、小写、数字和特殊字符,则加 10 分。 I have tried to use the.contain statement to try and differentiate it from the other addition if statements but it is giving me an error of Argument 1: Cannot Convert from 'method group' to 'string'and I don't know what to use to bypass it.我试图使用 .contain 语句来尝试将其与其他添加 if 语句区分开来,但它给了我参数 1 的错误:无法从“方法组”转换为“字符串”,我不知道该怎么做用来绕过它。

if (userPassword.Contains(char.IsUpper) &&
    userPassword.Contains(char.IsLower) &&
    userPassword.Contains(char.IsDigit) &&
    userPassword.Contains(c => specialCharacters.Contains(c)))
{
    points += 10;
}

If I'm understanding correctly, you want passwords which fit the "all uppercase," et cetera conditionals to subtract points while also NOT adding points for having a single uppercase.如果我理解正确,您希望密码适合“全大写”等条件来减去分数,同时也不为具有单个大写字母添加分数。 Like currently, "abc" in your example would receive +5 for having one lowercase, then would lose 5 for having all lowercase, evening out to 0 rather than -5.就像目前一样,您的示例中的“abc”将获得+5,因为有一个小写字母,然后会因为所有小写字母而失去5,最后是0而不是-5。

I would put your point-deducting conditionals into a single if statement at the beginning, then put all of your point-adding conditionals into if statements within an else statement:我会在开头将您的减分条件放入一个 if 语句中,然后将所有加分条件放入 else 语句中的 if 语句中:

 if (userPassword.All(char.IsLower) || userPassword.All(char.IsUpper) || userPassword.All(char.IsDigit) || userPassword.All(c => specialCharacters.Contains(c)) { points -= 5; } else { if (userPassword.Any(char.IsDigit)) { points += 5; } if (userPassword.Any(char.IsLower)) { points += 5; } if (userPassword.Any(char.IsUpper)) { points += 5; } if (userPassword.Any(c => specialCharacters.Contains(c))) { points += 5; } }

Alternatively, if you needed those point-deducting conditionals to be separated to allow for different values of point deductions for different conditions, just use more else if statements for the bad ones:或者,如果您需要将这些扣分条件分开以允许针对不同条件的不同扣分值,只需对坏的条件使用更多 else if 语句:

 if (userPassword.All(char.IsLower) || userPassword.All(char.IsUpper)) { points -= 5; } else if (userPassword.All(char.IsDigit)) { points -= 5; } else if (userPassword.All(c => specialCharacters.Contains(c))) { points -= 5; } else { if (userPassword.Any(char.IsDigit)) { points += 5; } if (userPassword.Any(char.IsLower)) { points += 5; } if (userPassword.Any(char.IsUpper)) { points += 5; } if (userPassword.Any(c => specialCharacters.Contains(c))) { points += 5; } }

Combine your "contradiction" check with the relevant "affirmation" check.将您的“矛盾”检查与相关的“确认”检查结合起来。 For example, when testing for containing a digit, also ensure they're not all digits:例如,在测试是否包含数字时,还要确保它们不都是数字:

if( userPassword.Any(char.isDigit)
    && !userPassword.All(char.isDigit) )
{
    points += 5;
}
else /*if(userPassword.All(char.isDigit)*/ // if desired
{
    points -= 5; // if appropriate
}

Now lets discuss restructuring your algorithm.现在让我们讨论重构你的算法。 Instead of defining long chains of if or if/else statements, let's create a class you can use to define your checks:让我们创建一个 class 来定义检查,而不是定义长链ifif/else语句:

public class PasswordEvaluator
{
    public Func<string, bool> TestCondition { get; init set; }
    public int AffirmativeResultValue { get; init set; }
    public int NegativeResultValue { get; init set; }

    public int Evaluate(string password) =>
        TestCondition(password)
            ? AffirmativeResultValue 
            : NegativeResultValue ;
}

Then you can define your tests.然后你可以定义你的测试。 Using the above solution:使用上述解决方案:

var hasDigitEvaluator = new PasswordEvaluator
{
    Condition = (string password) => password.Any(char.isDigit)
        && !password.All(char.isDigit),
    AffirmativeResultValue = 5,
    NegativeResultValue = -5, // or 0, whatever
};

Then you can use this object to perform the operation:然后可以使用这个 object 来执行操作:

points += hasDigitEvaluator.Evalutate(userPassword);

Now, to handle multiple evaluators, you can compose an IEnumerable<PasswordEvaluator> and then call a single operation over it to get your aggregate result:现在,要处理多个评估器,您可以编写一个IEnumerable<PasswordEvaluator> ,然后对其调用单个操作以获得聚合结果:

var passwordEvaluators = new[]
{
    new PasswordEvaluator { ... },
    new PasswordEvaluator { ... },
    ...
};

var points = passwordEvaluators
    .Select(test => test.Evaluate(userPassword))
    .Sum();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM