[英]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
参数)。
这里的问题是,由于您没有初始化变量userHeight
和userWeight
它们仍有可能保持垃圾值。
您可以尝试使用默认有效值初始化它们:
float userHeight = DEFAULT_HEIGHT;
float userWeight = DEFAULT_WEIGHT;
您为什么不想要使用一些负值来初始化变量,例如? 除非用户插入有效值,否则您的代码将无法结束
满足您的要求将无法达到本地范围的目的。 这样做不能有充分的理由。 在本地声明变量的目的是不要在更大范围内产生噪音。 就您而言,这不是噪音,您的userWidth和userHeight变量在主作用域中具有含义,因为您在此处使用了它们。 因此,您可以在方法中正确地对其进行初始化,或者在if中声明它们,并将使用它们的代码也移至if部分。 后者将意味着您有一些双重代码,可以通过将BMI的计算移到单独的方法并在两个if部分中调用该方法,将变量作为参数传递并返回BMI来解决。
将计算和输出语句放在同一方法中将是不好的。 但这是另一个故事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.