45 votes

Que signifie "Utilisation d'une variable locale non attribuée" ?

Je continue à obtenir cette erreur pour annualRate, monthlyCharge, et 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 votes

Je ne suggère pas de remplacer if-else déclarations de deux if . Ce n'est pas la meilleure façon de procéder. Avez-vous pensé à ce qui se passe si vous changez la valeur de creditPlan à l'intérieur d'un if déclaration ? Ou si vous appelez une fonction qui le modifie (pour qu'il ne soit pas aussi évident ) ? L'exécution pourrait alors entrer dans le prochain if et ce n'est pas ce que tu voulais dire.

0 votes

J'ai refait les instructions if avant de rendre ce programme. Je vous remercie pour votre aide, je n'y aurais pas pensé.

0 votes

Un billet en rapport aquí en fournissant des détails intéressants dans le fil de réponse.

4voto

StuartLC Points 35534

Il y a de nombreux chemins dans votre code où vos variables ne sont pas initialisées, c'est pourquoi le compilateur se plaint.

Spécifiquement, vous ne validez pas l'entrée de l'utilisateur pour creditPlan - si l'utilisateur entre une valeur autre que "0","1","2" or "3" alors aucune des branches indiquées ne sera exécutée (et creditPlan ne sera pas mis par défaut à zéro comme le demande votre utilisateur).

Comme d'autres l'ont mentionné, l'erreur du compilateur peut être évitée soit en initialisant par défaut toutes les variables dérivées avant que les branches ne soient vérifiées, soit en s'assurant qu'au moins une des branches est exécutée (c'est-à-dire l'exclusivité mutuelle des branches, avec une chute à travers les branches). else ).

Je voudrais toutefois signaler d'autres améliorations possibles :

  • Validez l'entrée de l'utilisateur avant de lui faire confiance pour l'utiliser dans votre code.
  • Modélisez les paramètres dans leur ensemble - il existe plusieurs propriétés et calculs applicables à chaque plan.
  • Utilisez des types plus appropriés pour les données, par ex. CreditPlan semble avoir un domaine fini et convient mieux à une enumeration ou Dictionary qu'un string . Les données financières et les pourcentages doivent toujours être modélisés sous forme de decimal pas double pour éviter les problèmes d'arrondi, et "status" semble être un booléen.
  • Asséchez le code répétitif. Le calcul, monthlyCharge = balance * annualRate * (1/12)) est commun à plus d'une branche. Pour des raisons de maintenance, ne pas dupliquer ce code.
  • Peut-être plus avancé, mais notez que les fonctions sont maintenant des citoyens de première classe de C#, donc vous pouvez assigner une fonction ou lambda comme une propriété, un champ ou un paramètre !

Par exemple, voici une représentation alternative de votre modèle :

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

3voto

lomaxx Points 32540

Vos affectations sont toutes imbriquées dans vos blocs conditionnels if, ce qui signifie qu'il est possible qu'elles ne soient jamais affectées.

Au début de votre classe, initialisez-les à 0 ou à une autre valeur.

1voto

Richard Schneider Points 16054

Le compilateur dit que annualRate n'aura pas de valeur si le CreditPlan n'est pas reconnu.

Lorsque vous créez les variables locales (annualRate, monthlyCharge et lateFee), attribuez-leur une valeur par défaut (0).

De même, vous devez afficher une erreur si le plan de crédit est inconnu.

0voto

Andrew Cooper Points 21126

Tous les chemins de code ne définissent pas une valeur pour lateFee . Vous voudrez peut-être lui attribuer une valeur par défaut en haut de la page.

0voto

David Points 1001

Vous n'attribuez pas de valeurs en dehors des instructions if ... et il est possible que le crédit soit autre chose que 0, 1, 2 ou 3, comme l'a noté @iomaxx.

Essayez de remplacer les instructions if séparées par un seul if/else if/else if/else. Ou attribuez des valeurs par défaut en haut de la page.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X