c# - unity - ¿Qué significa "Uso de variable local no asignada"?
use of unassigned local variable array (10)
Sigo recibiendo este error de AnnualRate, monthlyCharge y 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();
}
}
}
Cambia tus declaraciones a esto:
double lateFee = 0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
El error se debe a que hay al menos una ruta a través de su código donde estas variables terminan sin configurarse en nada.
Deles un valor predeterminado:
double lateFee=0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
Básicamente, todas las rutas posibles no inicializan estas variables.
El compilador dice que annualRate no tendrá valor si CreditPlan no es reconocido.
Al crear las variables locales (annualRate, monthlyCharge, y lateFee), asigne un valor predeterminado (0).
Además, debe mostrar un error si el plan de crédito es desconocido.
El compilador no es lo suficientemente inteligente como para saber que se ejecutará al menos uno de tus bloques if
. Por lo tanto, no ve que se le asignen variables como annualRate
sin importar qué. Así es como puedes hacer que el compilador entienda:
if (creditPlan == "0")
{
// ...
}
else if (creditPlan == "1")
{
// ...
}
else if (creditPlan == "2")
{
// ...
}
else
{
// ...
}
El compilador sabe que con un bloque if / else, se garantiza que se ejecutará uno de los bloques y, por lo tanto, si está asignando la variable en todos los bloques, no dará el error del compilador.
Por cierto, también puede usar una declaración de cambio en lugar de s para hacer que su código sea más limpio.
Hay muchas rutas a través de su código mediante las cuales sus variables no se inicializan, razón por la cual el compilador se queja.
Específicamente, no está validando la entrada del usuario para creditPlan
- si el usuario ingresa un valor de cualquier cosa que no sea "0","1","2" or "3"
, entonces ninguna de las ramas indicadas se ejecutará (y creditPlan
no será predeterminado a cero según el aviso del usuario).
Como han mencionado otros, el error del compilador puede evitarse mediante una inicialización predeterminada de todas las variables derivadas antes de que se verifiquen las ramas, o asegurando que se ejecute al menos una de las ramas (a saber, exclusividad mutua de las ramas, con una caída declaración else
).
Sin embargo, me gustaría señalar otras posibles mejoras:
- Valide la entrada del usuario antes de confiar en su uso en su código.
- Modele los parámetros como un todo: hay varias propiedades y cálculos aplicables a cada plan.
- Use tipos más apropiados para los datos. por ejemplo,
CreditPlan
parece tener un dominio finito y se adapta mejor a unaenumeration
oDictionary
que a unastring
. Los datos financieros y los porcentajes siempre se deben modelar comodecimal
, no comodouble
para evitar problemas de redondeo, y el ''estado'' parece ser un booleano. - SECAR el código repetitivo. El cálculo,
monthlyCharge = balance * annualRate * (1/12))
es común a más de una sucursal. Por razones de mantenimiento, no duplique este código. - Posiblemente más avanzado, pero tenga en cuenta que las funciones ahora son ciudadanos de primera clase de C #, por lo que puede asignar una función o lambda como una propiedad, campo o parámetro.
por ejemplo, aquí hay una representación alternativa de su modelo:
// 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
}
}
};
No se asignan valores fuera de las sentencias if ... y es posible que el crédito sea distinto de 0, 1, 2 o 3, como señaló @iomaxx.
Intente cambiar las sentencias if por separado a if / else si / else if / else. O asigne valores predeterminados arriba en la parte superior.
No todas las rutas de código establecen un valor para lateFee
. Es posible que desee establecer un valor predeterminado para él en la parte superior.
Porque si ninguna de las sentencias if se evalúa como verdadera, la variable local no se asignará. Lanza una instrucción else allí y asigna algunos valores a esas variables en caso de que las sentencias if no se evalúen como verdaderas. Publique aquí si eso no hace que el error desaparezca.
Su otra opción es inicializar las variables a algún valor predeterminado cuando las declare al comienzo de su código.
Si declara la variable "annualRate" como
Programa de clase {
**static double annualRate;**
public static void Main() {
Intentalo..
Sus asignaciones están anidadas dentro de sus bloques condicionales si, lo que significa que existe la posibilidad de que nunca sean asignados.
En la parte superior de tu clase, inicialízalos en 0 o en algún otro valor