“未分配本地变量的使用”是什么意思?

50
我一直在遇到annualRate、monthlyCharge和lateFee的错误。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lab_5___Danny_Curro
{
    class Program
    {
        static void Main(string[] args)
        {
            string firstName;
            string lastName;
            int accNumber;
            string creditPlan;
            double balance;
            string status;
            Boolean late = false;
            double lateFee;
            double monthlyCharge;
            double annualRate;
            double netBalance;


            Console.Write("Enter First Name: ");
            firstName = Console.ReadLine();

            Console.Write("Enter Last Name: ");
            lastName = Console.ReadLine();

            Console.Write("Enter Account Number: ");
            accNumber = Convert.ToInt32(Console.ReadLine());


            Console.Write("Enter Credit Card Plan Number[Blank Will Enter Plan 0]: ");
            creditPlan = Console.ReadLine();

            Console.Write("Enter Balance: ");
            balance = Convert.ToDouble(Console.ReadLine());

            Console.Write("Is This Account Late?: ");
            status = Console.ReadLine().Trim().ToLower();

            if (creditPlan == "0")
            {
                annualRate = 0.35;  //35%
                lateFee = 0.0;
                monthlyCharge = balance * (annualRate * (1 / 12));
                return;
            }

            if (creditPlan == "1")
            {
                annualRate = 0.30;  //30%
                if (status == "y")
                {
                    late = true;
                }

                else if (status == "n")
                {
                    late = false;
                }
                if (late == true)
                {
                    lateFee = 25.00;
                }
                monthlyCharge = balance * (annualRate * (1 / 12));
                return;
            }
            if (creditPlan == "2")
            {
                annualRate = 0.20;  //20%
                if (status == "y")
                {
                    late = true;
                }

                else if (status == "n")
                {
                    late = false;
                }
                if (late == true)
                {
                    lateFee = 35.00;
                }
                if (balance > 100)
                {
                    monthlyCharge = balance * (annualRate * (1 / 12));
                }
                else
                {
                    monthlyCharge = 0;
                }
                return;
            }
            if (creditPlan == "3")
            {
                annualRate = 0.15;  //15%
                lateFee = 0.00;

                if (balance > 500)
                {
                    monthlyCharge = (balance - 500) * (annualRate * (1 / 12));
                }
                else
                {
                    monthlyCharge = 0;
                }
                return;
            }
            netBalance = balance - (lateFee + monthlyCharge);


            Console.WriteLine("Name: \t\t\t {0}  {1}", firstName, lastName);
            Console.WriteLine("Account Number: \t{0}", accNumber);
            Console.WriteLine("Credit Plane: \t\t{0}",creditPlan);
            Console.WriteLine("Account Late: \t\t{0}", late);
            Console.WriteLine("Balance: \t\t{0}", balance);
            Console.WriteLine("Late Fee: \t\t{0}", lateFee);
            Console.WriteLine("Interest Charge: \t{0}", monthlyCharge);
            Console.WriteLine("Net Balance: \t\t{0}",netBalance);
            Console.WriteLine("Annual Rate: \t\t{0}", annualRate);
            Console.ReadKey();
        }
    }
}

3
我不建议用两个if语句来替换if-else语句,这不是最好的做法。你有没有考虑过如果在一个if语句中改变了creditPlan的值会发生什么?或者如果调用一个改变它的函数(让它不再那么显然)?那么执行可能会进入下一个if,而这不是你想要的。 - Oscar Mederos
我在提交这个程序之前重新编写了if语句。谢谢你的帮助,否则我不会想到那个方法。谢谢。 - Daniel Curro
这里有一个相关的帖子链接,其中提供了有趣的细节在回答线程中。 - RBT
11个回答

71
编译器并不聪明,不能确定你的if块中至少有一个会被执行。因此,它无法看到像annualRate这样的变量无论如何都将被赋值。以下是让编译器理解的方法:
if (creditPlan == "0")
{
    // ...
}
else if (creditPlan == "1")
{
    // ...
}
else if (creditPlan == "2")
{
    // ...
}
else
{
    // ...
}
编译器知道在 if/else 代码块中,其中一个代码块一定会执行。因此,如果你在所有代码块中都进行变量赋值,编译器不会报错。 另外,你也可以使用 switch 语句来代替 if 语句,这样可能会使你的代码更清晰。

非常感谢,这真的很有帮助。我想感谢每个人,但没有时间评论每个人的回复。所以谢谢。 - Daniel Curro
4
来晚了一点,但是如果有意义的话,您也可以为annualRate实例化一个默认值。 - Jon Story

20

请将您的声明更改为以下内容:

double lateFee = 0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;

出现此错误是因为您的代码中存在至少一条路径,导致这些变量没有被设置为任何值。


12

给它们一个默认值:

double lateFee=0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;

基本上,所有可能的路径都不会初始化这些变量。


12
因为如果所有的if语句都不为真,则本地变量将未被分配。在其中添加else语句并为这些变量分配一些值,以防if语句不为真。如果这样做无法消除错误,请在此回复。
您的另一个选择是在代码开头声明时将变量初始化为某个默认值。

10

请使用关键字“默认”!!!

    string myString = default;
    double myDouble = default;

    if(!String.IsNullOrEmpty(myString))
       myDouble = 1.5;

    return myDouble;

4
你的代码存在许多路径导致变量未初始化,这就是编译器抱怨的原因。具体而言,你没有验证用户输入的creditPlan - 如果用户输入的值不是"0", "1", "2"或"3"中的任何一个,那么不会执行任何指示的分支(并且根据您的用户提示,creditPlan将不会默认为零)。正如其他人所提到的,可以通过在检查分支之前进行派生变量的默认初始化,或者确保至少执行其中一个分支(即,分支的相互排斥性,使用else语句进行脱落)来避免编译器错误。 然而,我想指出其他潜在的改进: - 在信任代码之前验证用户输入。 - 将参数建模为整体 - 适用于每个计划的几个属性和计算。 - 使用更合适类型的数据。例如,CreditPlan似乎有一个有限的域,并且更适合于枚举或字典而不是字符串。金融数据和百分比应始终建模为decimal而不是double以避免舍入问题,并且“状态”似乎是布尔值。 - DRY重复的代码。计算monthlyCharge = balance * annualRate * (1/12))是多个分支共同的内容。为了维护方便,请勿重复此代码。 - 可能更高级,但请注意,函数现在是C#的一级公民,因此您可以将函数或lambda分配为属性,字段或参数!。 例如,这里是您的模型的另一种替代表示形式:
    // Keep all Credit Plan parameters together in a model
    public class CreditPlan
    {
        public Func<decimal, decimal, decimal> MonthlyCharge { get; set; }
        public decimal AnnualRate { get; set; }
        public Func<bool, Decimal> LateFee { get; set; }
    }

    // DRY up repeated calculations
    static private decimal StandardMonthlyCharge(decimal balance, decimal annualRate)
    { 
       return balance * annualRate / 12;
    }

    public static Dictionary<int, CreditPlan> CreditPlans = new Dictionary<int, CreditPlan>
    {
        { 0, new CreditPlan
            {
                AnnualRate = .35M, 
                LateFee = _ => 0.0M, 
                MonthlyCharge = StandardMonthlyCharge
            }
        },
        { 1, new CreditPlan
            {
                AnnualRate = .30M, 
                LateFee = late => late ? 0 : 25.0M,
                MonthlyCharge = StandardMonthlyCharge
            }
        },
        { 2, new CreditPlan
            {
                AnnualRate = .20M, 
                LateFee = late => late ? 0 : 35.0M,
                MonthlyCharge = (balance, annualRate) => balance > 100 
                    ? balance * annualRate / 12
                    : 0
            }
        },
        { 3, new CreditPlan
            {
                AnnualRate = .15M, 
                LateFee = _ => 0.0M,
                MonthlyCharge = (balance, annualRate) => balance > 500 
                    ? (balance - 500) * annualRate / 12
                    : 0
            }
        }
    };

3

你的任务都嵌套在条件语句中,这意味着它们有可能永远不会被分配。

在类的顶部将它们初始化为0或其他值。


1
编译器提示如果未识别信用计划,则annualRate将没有值。
在创建本地变量(annualRate、monthlyCharge和lateFee)时,为它们分配默认值(0)。
此外,如果信用计划未知,应显示错误。

0
如果您像这样声明变量“annualRate”
类程序 {
**static double annualRate;**

public static void Main() {

试一下吧...


0
并非所有的代码路径都为lateFee设置了一个值。您可能希望在顶部为其设置一个默认值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接