-3

我正在制作一个密码生成器,我有三个复选框:小写字母、大写字母和数字。现在我有一个 IF 声明说:

    IF (check1.checked == true & check2.checked == true & check3.checked == true)
       {
           length = Convert.ToInt32(lengthTextBox.Text);
                string password = "";
                int choice;
                Generate gen = new Generate();
                for (int i = 1; i <= length; i++)
                {
                    choice = rnd.Next(1, 4);
                    if (choice == 1)
                    {
                        password = password + gen.lower();
                    }
                    else if (choice == 2)
                    {
                        password = password + gen.upper();
                    }
                    else if (choice == 3)
                    {
                        password = password + gen.number();
                    }
                }

                passwordTextBox.Text = password;
       }
    Else IF (check1.checked == true & check2.checked == true)
    {
            length = Convert.ToInt32(lengthTextBox.Text);
                string password = "";
                int choice;
                Generate gen = new Generate();
                for (int i = 1; i <= length; i++)
                {
                    choice = rnd.Next(1, 3);
                    if (choice == 1)
                    {
                        password = password + gen.lower();
                    }
                    else if (choice == 2)
                    {
                        password = password + gen.upper();
                    }
                }

                passwordTextBox.Text = password;
    }

等等。这种方法效率极低。我在制作收银机程序时遇到了这个问题(10种浇头选择,检查你想要的,程序将价格加在一起。如果你取消选中一个浇头,价格将减去那个数量。),所以我只是放弃了。但现在,我决心找到一种隐喻购物的方式。

4

6 回答 6

4

虽然不清楚您的代码做了什么,但您似乎可以连续调用这些方法。那么为什么不这样做呢?

if (check1.Checked)
   Generate.lowercase();

if (check2.Checked)
   Generate.uppercase();

if (check3.Checked)
   Generate.number();

此外,您可能应该为您的控件和变量使用更具描述性的名称。

于 2013-10-07T14:56:29.227 回答
1
if(check1.checked) Generate.lowercase();
if(check2.checked) Generate.uppercase();
...
于 2013-10-07T14:56:31.853 回答
0

所以你在这里真正需要做的是找到一种使选择动态的方法。这样做的一种方法是创建一个函数列表,其中每个函数都能够生成一个值。在开始时,您根据检查的内容使用相关函数填充列表,然后您可以有一个循环,只需从该列表中选择一个函数:

List<Func<char>> generators = new List<Func<char>>();
if (lowercaseCheckbox.Checked)
    generators.Add(() => gen.lowercase());

if (uppercaseCheckbox.Checked)
    generators.Add(() => gen.uppercase());

if (numberCheckbox.Checked)
    generators.Add(() => gen.number());

int length = Convert.ToInt32(lengthTextBox.Text);
StringBuilder password = new StringBuilder();
Random random = new Random();
for (int i = 0; i < length; i++)
{
    int choice = random.Next(generators.Count);
    password.Append(generators[choice]());
}
string result = password.ToString();

请注意,您应该使用 aStringBuilder来避免不断地重新分配和复制值,而不是在循环中重复地将字符附加到字符串。

checkbox我还建议为变量使用更有意义的名称;它使代码更具可读性。

于 2013-10-07T14:56:35.253 回答
0

这取决于您使用的框架和应用的模式,但有更好的方法可以做到这一点。您可以使用位标志并将复选框和它们放在一起。

FlagVariable output = FlagVariable.None;
if( topping1.IsChecked )
{
    output &= FlagVariable.Topping1;
}
if( topping2.IsChecked )
{
    output &= FlagVariable.Topping2;
}
// etc...

然后稍后

if( output | FlagVariable.Topping1 )
{
    // it has topping 1
}

这是非常有效和可维护的。您仍然需要在复选框及其对应的标志值之间编写关联代码(这部分取决于您的框架/模式,因为在带有 MVVM 的 WPF 中,您可能能够避免大量的 if-then 代码) .

于 2013-10-07T14:57:05.380 回答
0

你可以简单地把它们分开:

if (check1.checked) Generate.lowercase();
if (check2.checked) Generate.upperrcase();
if (check3.checked) Generate.number();

从逻辑上讲,这种方式与分组方式之间没有关系。

于 2013-10-07T14:57:29.757 回答
0

如果密码生成@Gerald Versluis 的答案,绝对值得一看。

在购物的情况下,你有味道。“检查”口味,然后添加“检查”口味的价格,它只是不能很好地扩展,正如您已经意识到的那样。
在这种情况下,最好将口味添加到列表中,然后将其计算为总数。

这也可以应用于密码生成。您可以在其中添加不同的“密码”生成器,从而让它更好地扩展,并使用 C# 强大的 OOP 功能。这里的流行语是:Polymorhism

于 2013-10-07T15:02:19.017 回答