验证返回False,然后继续执行程序

时间:2020-09-16 17:49:37

标签: c# validation

编辑添加:给我的问题就在于使用包含18个不同帐号的文本文件。我可以选择使程序将其读取到数组或List<>中。然后,该程序应允许用户输入一个数字,并确定它是否与数组/ List<>中的一个实体相匹配,显示它是有效/无效。

花了我一段时间,我的代码才能正常工作。现在,我不介意在返回false的错误输入验证之后,后面的方法一直在运行,从而产生了第二个弹出窗口。但是,有时会很烦人。就像我说的那样,它运行良好,但是我想找出是否有一种方法可以使它在验证返回false的情况下停止运行其余部分。

private void ReadAccNums(int[] accountNumArray)
        {
            // Try-catch to prevent file error issues.
            try
            {
                // Increment num var.
                int num = 0;

                // Open ChargeAccounts.txt file.
                StreamReader accNumsFile = File.OpenText("ChargeAccounts.txt");

                // Read account numbers into array.
                while (num < accountNumArray.Length && !accNumsFile.EndOfStream)
                {
                    // Put each item into accountNumArray.
                    accountNumArray[num] = int.Parse(accNumsFile.ReadLine());
                    num++;
                }

                // Close file.
                accNumsFile.Close();
            }
            catch (Exception ex)
            {
                // Display error message.
                MessageBox.Show(ex.Message);
            }
        }
        // Method to handle TextBox input 
        // validation.
        private bool InputIsValid(ref int accNum)
        {
            // Flag to make sure input is good.
            bool inputValid = false;

            // Get and validate accountNumbersAccessTextBox input.
            if (int.TryParse(accountNumberAccessTextBox.Text, out accNum))
            {
                // Did we get this far? Confirm input validation.
                inputValid = true;
            }
            // Display error message for accNum.
            else
            {
                MessageBox.Show("Please input a non-decimal, seven digit number" +
                    " for the account number.");

                // Reset Focus to accountNumbersAccessTextBox.
                accountNumberAccessTextBox.Focus();
            }

            // Return result.
            return inputValid;
        }

        // Method to find out if input
        // has a match in ChargeAccounts.txt.
        private int AccNumSearch(int accNum,
            int[] accountNumArray)
        {
            // Bool flag for matching accNum.
            bool accNumFound = false;

            // Index var.
            int num = 0;

            // Position of Sequential Search.
            int position = -1;

            // Get input from TextBox.
            if (InputIsValid(ref accNum))
            {
                // Read through array to find 
                // matching accNum.
                while (!accNumFound && num < accountNumArray.Length)
                {
                    if (accountNumArray[num] == accNum)
                    {
                        // Found a match? Yay! Access granted!
                        accNumFound = true;
                        position = num;
                    }

                    num++;
                }
            }
            // Return.
            return position;
        }

        // Method to determine whether input
        // matches an account number.
        private bool AccNumMatch(int[] accountNumArray,
            ref int accNum)
        {
            // Bool flag to confirm
            // matching accNum.
            bool accNumMatch = false;

            // Got a match? Tell the user.
            if (AccNumSearch(accNum, accountNumArray) != -1)
            {
                accNumMatch = true;
                MessageBox.Show("Account number correct. Access granted.");
            }
            else
            {
                // No match? Alas.
                MessageBox.Show("Account number invalid. Access denied.");
            }

            // Return.
            return accNumMatch;
        }
        private void accountNumberAccessButton_Click(object sender, EventArgs e)
        {
            // Declare array to be filled by
            // ReadAccNums method.
            const int SIZE = 18;
            int[] accountNumArray = new int[SIZE];

            // Get the account numbers.
            ReadAccNums(accountNumArray);

            // Var for accNum to ref.
            int accNum = 0;

            // Is our account number correct?
            AccNumMatch(accountNumArray, ref accNum);
        }

1 个答案:

答案 0 :(得分:0)

您的代码似乎非常冗长,无法执行以下操作:

  • 用户在文本框中输入数字
  • 程序检查其数字
  • 程序检查文件中是否存在

如果我被要求编写这样的代码,我可能会:

void Login_Click(object sender, EventArgs e){

  if(!int.TryParse(accountNumberTextbox.Text, out int seeking)) {
    MessageBox.Show("The account number text does not appear to be numeric");
    return;
  }

  accNumMatch = File.ReadLines("c:\\temp\\accountnumbers.txt").Any(line => line == accountNumberTextbox.Text));

  if(accNumMatch) {
    MessageBox.Show("Account number correct. Access granted.");
  }
  else {
    MessageBox.Show("Account number invalid. Access denied.");
  }
}

因为将文件内容转换为数字然后搜索数字根本没有任何意义;确保用户输入的是数字之后,将它们保留为字符串并比较字符串更为简单

如果我使用了numericupdown,那么用户甚至无法输入非数字:

void Login_Click(object sender, EventArgs e){

  accNumMatch = File.ReadLines("c:\\temp\\accountnumbers.txt").Any(line => line == accountNumberNumericUpDown.Value.ToString()));

  if(accNumMatch) {
    MessageBox.Show("Account number correct. Access granted.");
  }
  else {
    MessageBox.Show("Account number invalid. Access denied.");
  }
}

您可以将输入的内容转换为文本,然后直接启动以读取文件并查找包含输入内容的行


我感谢您可能正在学习,因此使用LINQ有点作弊,但即使这样:

void Login_Click(object sender, EventArgs e){

  if(!int.TryParse(accountNumberTextbox.Text, out int seeking)) {
    MessageBox.Show("The account number text does not appear to be numeric");
    return;
  }

  
  accNumMatch = false;

  StreamReader accNumsFile = File.OpenText("ChargeAccounts.txt");
  while (!accNumsFile.EndOfStream && !accNumMatch)
  {
    string line = accNumsFile.ReadLine();
    accNumMatch = (line == accountNumberTextbox.Text);
  }
}

我将暂时不讲授有关使用/确保您现在关闭并处置文件阅读器等的信息;)


如果必须将文件读取到数组中,则可以使用System.IO.File.ReadAllLines()作为读取文件的快速方法。我不会在这里使用它,但是如果您想看的话可以查一下


如果您必须从一个文件中读取多达X行,请读取一个int数组,然后查看是否有任何int是您要寻找的int:

void Login_Click(object sender, EventArgs e){

  bool validInput = int.TryParse(accountNumberTextbox.Text, out int seeking);
  if(!validInput) {
    MessageBox.Show("The account number text does not appear to be numeric");
    return;
  }

  
  int[] numbers = new int[100];

  StreamReader accNumsFile = File.OpenText("ChargeAccounts.txt");

  for(int i = 0; i < numbers.Length && !accNumsFile.EndOfStream; i++)
  {
    string line = accNumsFile.ReadLine();
    numbers[i] = int.Parse(line);
  }


  accNumMatch = false;

  foreach(int number in numbers){
    if(number == seeking) { //seeking comes from earlier
      accNumMatch = true;
      break;
    }
  }
}

您可以将它们分解为单独的方法。制作一个接受输入并给出输出的方法:

void Login_Click(object sender, EventArgs e){

  int seek = ConvertToAccountNumber(accountNumberTextbox.Text);

  if(seek == -1){
    MessageBox.Show("Enter a valid number");
    return
  }

  int[] numbers = GetAccountNumbersInFile("ChargeAccounts.txt");

  accNumMatch = ArrayContainsNumber(numbers, seek);


}

//this is basically a variation of int.Parse/int.TryParse
public int ConvertToAccountNumber(string s){

  bool validInput = int.TryParse(accountNumberTextbox.Text, out int seeking);
  if(!validInput)
    return -1; //we will use -1 to signify invalid input, because no account number is ever -1
  else
    return seeking;

}

//File.ReadAllLines can help with this, as can LINQ Select/int parse
public int[] GetAccountNumbersInFile(string p){

  int[] numbers = new int[100];

  StreamReader accNumsFile = File.OpenText(p);

  for(int i = 0; i < numbers.Length && !accNumsFile.EndOfStream; i++)
  {
    string line = accNumsFile.ReadLine();
    numbers[i] = int.Parse(line);
  }
}

//there exist helper methods for doing this too, look at the Array class - https://docs.microsoft.com/en-us/dotnet/api/system.array?view=netcore-3.1
public bool ArrayContainsNumber(int[] array, int seeking){

  foreach(int number in numbers){
    if(number == seeking) {
      return true;
    }
  }

  return false;
}

我知道您为什么使用ref 为什么,但应避免使用它。实际上,框架在将文本解析为数字并返回布尔值以指示成功和数字时使用out,但是您可以轻松地采用string.IndexOf这样的方法-如果返回{-1大海捞针中找不到针。您(可能)还没有了解异常,但这也将是使用它们的机会-如果输入数据不好,则抛出异常而不是返回值

总而言之,这是out在您职业生涯中可能很合理的少数几个地方之一,因此,如果有必要,请使用它(出于学术原因,但不要使用ref-ref是为了在使用变量的值之前可能会使用它的值的方式引入变量的方法。这是out场景,其中输入变量不应该有值,并且将被该方法覆盖),但是