Подтвердить что ты не робот

Что означает "Использование неназначенной локальной переменной"?

Я продолжаю получать эту ошибку для годовых, ежемесячных и поздних платежей.

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();
        }
    }
}
4b9b3361

Ответ 1

Компилятор недостаточно умен, чтобы знать, что будет выполнен хотя бы один из ваших блоков if. Поэтому он не видит, что переменные типа annualRate будут назначены независимо от того, что. Вот как вы можете понять компилятор:

if (creditPlan == "0")
{
    // ...
}
else if (creditPlan == "1")
{
    // ...
}
else if (creditPlan == "2")
{
    // ...
}
else
{
    // ...
}

Компилятор знает, что с блоком if/else гарантируется выполнение одного из блоков, и поэтому, если вы назначаете переменную во всех блоках, она не даст ошибку компилятора.

Кстати, вы также можете использовать оператор switch вместо if, чтобы сделать ваш код более чистым.

Ответ 2

Измените свои объявления на это:

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

Ошибка вызвана тем, что через ваш код, по крайней мере, один путь, где эти переменные не получают никакого значения.

Ответ 3

Потому что, если ни один из операторов if не оценивает значение true, локальная переменная будет не назначена. Выбросьте в нем инструкцию else и присвойте некоторые значения этим переменным в случае, если утверждения if не оцениваются как true. Отправляйтесь сюда, если это не приведет к ошибке.

Другой вариант - инициализировать переменные до некоторого значения по умолчанию, когда вы объявляете их в начале вашего кода.

Ответ 4

Дайте им значение по умолчанию:

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

В принципе, все возможные пути не инициализируют эти переменные.

Ответ 5

Ваши назначения все вложены в ваш условный, если блоки, что означает, что у них есть потенциальная возможность никогда не назначаться.

В верхней части вашего класса инициализируйте их до 0 или другого значения

Ответ 6

В коде есть много путей, из-за которых ваши переменные не инициализируются, поэтому компилятор жалуется.

В частности, вы не проверяете ввод пользователя для creditPlan - если пользователь вводит значение чего-либо еще, кроме "0","1","2" or "3", то ни одна из указанных ветвей не будет выполнена (а creditPlan не будет использоваться по умолчанию ноль в соответствии с запросом вашего пользователя).

Как уже упоминалось, ошибки компилятора можно избежать либо инициализацией по умолчанию всех производных переменных перед проверкой ветвей, либо гарантией выполнения хотя бы одной из ветвей (а именно, взаимной исключительности ветвей с помощью падение через инструкцию else).

Я хотел бы отметить другие потенциальные улучшения:

  • Подтвердите ввод пользователя, прежде чем доверять ему для использования в вашем коде.
  • Моделировать параметры в целом - для каждого плана есть несколько свойств и расчетов.
  • Используйте более подходящие типы данных. например creditPlan, как представляется, имеет конечный домен и лучше подходит для enumeration или Dictionary, чем a string. Финансовые данные и проценты всегда должны быть моделированы как decimal, а не double, чтобы избежать проблем округления, а "статус" выглядит логическим.
  • DRY повторяющийся код. Расчет, monthlyCharge = balance * annualRate * (1/12)) является общим для более чем одной ветки. По причинам технического обслуживания не дублируйте этот код.
  • Возможно, более продвинутый, но обратите внимание, что функции теперь являются гражданами первого класса С#, поэтому вы можете назначить функцию или лямбда как свойство, поле или параметр!.

например. вот альтернативное представление вашей модели:

    // 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
            }
        }
    };

Ответ 7

Компилятор говорит, что у гостяRate не будет значения, если CreditPlan не будет распознан.

При создании локальных переменных (annualRate, monthCharge и lateFee) присваивает им значение по умолчанию (0).

Кроме того, вы должны показать ошибку, если кредитный план неизвестен.

Ответ 8

Не все пути кода задают значение для lateFee. Вы можете установить для него значение по умолчанию вверху.

Ответ 9

Вы не присваиваете значения за пределами операторов if... и возможно, что кредит может быть чем-то отличным от 0, 1, 2 или 3, как отметил @iomaxx.

Попробуйте сменить отдельные операторы if на один if/else if/else if/else. Или назначьте значения по умолчанию вверху.

Ответ 10

Если вы объявите переменную "годовойRate", как

программа класса {

**static double annualRate;**

public static void Main() {

Попробуйте.