簡體   English   中英

如何在C#中引用超出范圍的變量

[英]How to reference a variable outside of scope in C#

我的教授要求我們創建一個吸收用戶身高和體重的程序,然后計算bmi。 我決定更進一步,並添加了一些“輸入驗證”邏輯。 這意味着,如果有人輸入“ cat”作為其體重,它會讓用戶知道“ cat”不是有效的體重。

class MainClass
{
    public static void Main ()
    {
        float userWeight;
        float userHeight;           
        bool weight = true;
        Console.Write ("Weight:  ");
        while (weight) 
        {               
            var inputWeight = (Console.ReadLine ());
            if (!float.TryParse (inputWeight, out userWeight)) {
                Console.WriteLine ("Invalid input");
                Console.Write ("Please try again: ");
            } 
            else 
            {
                weight = false;
            }
        }
        bool height = true;
        Console.Write ("Height:  ");
        while (height) 
        {
            var inputHeight = (Console.ReadLine ());
            if (!float.TryParse (inputHeight, out userHeight)) {
                Console.WriteLine ("Invalid input");
                Console.Write ("Please try again: ");
            } 
            else 
            {
                height = false;
            }
        }
        float bmiHeight = userHeight * userHeight; // error for userHeight
        float bmi = userWeight / bmiHeight * 703;  // error for userWeight
        Console.WriteLine ("You BMI is " + bmi);
    }           
}

我得到的錯誤是“使用未分配的局部變量..”。 我知道我正在IF語句中分配用戶變量,並且它們僅會持續到該IF語句結束。

我的問題是,如何在if語句中分配變量,然后在該語句之外引用該變量的新值?

當然,我不必全部嵌套,因為這似乎很乏味。

public void heightAndWeight()
    {
        double height = getValue("What is your height in inches?",36,80);
        double weight = getValue("What is your weight in kilograms?",45,135);
        if (height > 0 && weight > 0)
        {
            Console.WriteLine("your BMI is " + (height * weight).ToString("N2"));
        }
    }
    private double getValue(string question,int lowRange,int highRange) {
        double ret = 0;
        while(ret==0){
            Console.WriteLine(question);
            string retStr = Console.ReadLine();
            if(double.TryParse(retStr,out ret))
            {
                if(ret<lowRange||ret>highRange){
                   Console.WriteLine("You must enter a value between "+lowRange.ToString()+" and "+highRange.ToString()+". Please try again.");
                   ret=0;
                 }else{
                    return ret;
                 }
            }else{
                Console.WriteLine("Invalid entry. Please try again");
            }
        }
        return ret;
    }

Do ... while(condition)更適合您的情況,並且還允許編譯器確認值實際上已分配:

    var isHeightValid = false;
    do 
    {
        var inputHeight = (Console.ReadLine ());
        if (!float.TryParse (inputHeight, out userHeight)) {
            Console.WriteLine ("Invalid input");
            Console.Write ("Please try again: ");
        } 
        else 
        {
            isHeightValid = false;
        }
    }
    while (!isHeightValid);

原因:編譯器不夠聰明,無法確定一般情況下while(condition)第一次迭代將始終執行,因此它假定while內的代碼可能不會運行,因此變量將不會被賦值。 是的,在您的特定情況下,實際上可以檢測到第一次迭代運行,但是這種情況可能不足以向編譯器添加規則。

do ... while另一方面,保證至少發生一次迭代,因此從編譯器的角度來看,始終會發生變量分配(通過out參數)。

這里的問題是,由於您沒有初始化變量userHeightuserWeight它們仍有可能保持垃圾值。

您可以嘗試使用默認有效值初始化它們:

float userHeight = DEFAULT_HEIGHT;
float userWeight = DEFAULT_WEIGHT;

您為什么不想要使用一些負值來初始化變量,例如? 除非用戶插入有效值,否則您的代碼將無法結束

滿足您的要求將無法達到本地范圍的目的。 這樣做不能有充分的理由。 在本地聲明變量的目的是不要在更大范圍內產生噪音。 就您而言,這不是噪音,您的userWidth和userHeight變量在主作用域中具有含義,因為您在此處使用了它們。 因此,您可以在方法中正確地對其進行初始化,或者在if中聲明它們,並將使用它們的代碼也移至if部分。 后者將意味着您有一些雙重代碼,可以通過將BMI的計算移到單獨的方法並在兩個if部分中調用該方法,將變量作為參數傳遞並返回BMI來解決。

將計算和輸出語句放在同一方法中將是不好的。 但這是另一個故事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM