这是 goto 语句的好用法吗?

Is this a good use of goto statement?

我正在编写一个简单的 C# 控制台应用程序,如果 UserId 的输入无效,我将在其中通过使用 GoTo 语句 return 到标签来解决问题。

但我不确定我是否正确使用了该语句。如果有更好的方法来解决问题,即使不使用 GoTo 语句,我也想变通?

public void CreateAccount()
{
    Console.WriteLine("----- Create New Account -----\n" +
        "Enter following account information:\n");

    getUserID:
    {
        Console.WriteLine("Enter a UserID (Alphanumeric; no special characters): ");
        string userid = Console.ReadLine();
        if (!ValidUserID(userid))
        {
            Console.WriteLine("Userid can only contain A-Z, a-z & 0-9. Try again");
            goto getUserID;
        }
        if (data.IsUserInFile(userid))
        {
            Console.WriteLine("Userid already exists. Try again");
            goto getUserID;
        }
    }
}

我将对 Pin、AccountType、Balance、AccountStatus 等其他字段使用相同的方法,因此我想确保在扩展其用途之前以正确的方式执行此操作。

一个简单的方法是使用 if/else if/else 结构:

public void CreateAccount()
{
    Console.WriteLine("----- Create New Account -----\n" +
        "Enter following account information:\n");

    string userid = null;
    while (true)
    {
        Console.WriteLine("Enter a UserID (Alphanumeric; no special characters): ");
        userid = Console.ReadLine();
        if (!ValidUserID(userid))
        {
            Console.WriteLine("Userid can only contain A-Z, a-z & 0-9. Try again");
        }
        // if the condition above isn't matched, we'll check this condition
        else if (data.IsUserInFile(userid))
        {
            Console.WriteLine("Userid already exists. Try again");
        }
        // if that isn't matched either, then we have an acceptable userid and can exit the loop
        else
        {
            break;
        }
    }
}

请注意,我已将 userid 声明移出循环,因为您可能需要在循环后使用它。

或者,您可能会进一步分解您的代码。读取 userId 的整个方法可以移出到它自己的方法中:

public string ReadUserId()
{
    while(true)
    {
        // Prompt and read answer
        Console.WriteLine("Enter a UserID (Alphanumeric; no special characters): ");
        string userId = Console.ReadLine();
        
        // If the id is valid, return it and leave the method (ending the loop)
        if (ValidUserId(userId))
        {
            return userId;
        }
        
        // If we got here, then the id is invalid and we should inform the user to try again
        Console.WriteLine("Userid can only contain A-Z, a-z & 0-9. Try again");
    }
}

现在main方法中我们需要获取userId的时候可以引用这个方法。用于检查用户是否已经存在的循环现在可以单独实现以读取用户输入,因此不再担心两种不同的情况:

public void CreateAccount()
{
    Console.WriteLine("----- Create New Account -----\n" +
        "Enter following account information:\n");

    string userId = null;
    bool isNewUser = false;
    while (!isNewUser)
    {       
        // Use our other method to read the user id
        userId = ReadUserId();
    
        if (data.IsUserInFile(userId))
        {
            Console.WriteLine("Userid already exists. Try again");
            continue;
        }
        
        isNewUser = true;
    }
}