44

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

11 に答える 11

66

コンパイラは、少なくとも1つのifブロックが実行されることを知るほど賢くはありません。annualRateしたがって、のような変数が何があっても割り当てられることはわかりません。コンパイラに理解させる方法は次のとおりです。

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

コンパイラは、if / elseブロックを使用すると、ブロックの1つが実行されることが保証されていることを認識しているため、すべてのブロックに変数を割り当てても、コンパイラエラーは発生しません。

ちなみに、 sのswitch代わりにステートメントを使用しifて、コードをよりクリーンにすることもできます。

于 2011-04-19T01:08:42.643 に答える
19

宣言を次のように変更します。

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

これらの変数が何も設定されないコード内のパスが少なくとも 1 つあるため、エラーが発生します。

于 2011-04-19T01:08:37.440 に答える
12

if ステートメントのいずれも true と評価されない場合、ローカル変数は割り当てられないためです。そこにelseステートメントを投げて、ifステートメントがtrueと評価されない場合に備えて、それらの変数にいくつかの値を割り当てます。それでもエラーが解消されない場合は、ここに投稿してください。

他のオプションは、変数をコードの最初で宣言するときに、変数をデフォルト値に初期化することです。

于 2011-04-19T01:06:06.717 に答える
10

それらにデフォルト値を与えます:

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

基本的に、すべての可能なパスがこれらの変数を初期化するわけではありません。

于 2011-04-19T01:09:52.493 に答える
4

変数が初期化されていないコード内の多くのパスがあり、コンパイラが不平を言うのはそのためです。

具体的には、ユーザー入力を検証していません。ユーザーcreditPlanが 以外の値を入力した場合、"0","1","2" or "3"指定されたブランチは実行されcreditPlanません (また、ユーザー プロンプトに従ってデフォルトでゼロに設定されません)。

他の人が述べたように、分岐がチェックされる前にすべての派生変数をデフォルトで初期化するか、少なくとも1つの分岐が実行されるようにすることで、コンパイラエラーを回避できます(つまり、フォールスルーを伴う分岐の相互排他性)else声明)。

ただし、他の潜在的な改善点を指摘したいと思います。

  • コードでの使用を信頼する前に、ユーザー入力を検証します。
  • パラメーターを全体としてモデル化します。各計画に適用できるいくつかのプロパティと計算があります。
  • より適切なデータ型を使用してください。egは有限領域を持っているように見え、 orよりもorCreditPlanに適しています。四捨五入の問題を回避するためではなく、財務データとパーセンテージは常に としてモデル化する必要があり、「ステータス」はブール値のように見えます。enumerationDictionarystringdecimaldouble
  • 反復コードをドライアップします。計算monthlyCharge = balance * annualRate * (1/12))は、複数のブランチに共通です。メンテナンス上の理由から、このコードを複製しないでください。
  • もっと高度かもしれませんが、関数は現在 C# の第一級市民であるため、関数またはラムダをプロパティ、フィールド、またはパラメーターとして割り当てることができることに注意してください。

たとえば、モデルの代替表現は次のとおりです。

    // 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
            }
        }
    };
于 2014-08-08T20:46:54.650 に答える
3

割り当てはすべて、条件付きの if ブロック内にネストされています。つまり、割り当てられない可能性があります。

クラスの先頭で、それらを 0 またはその他の値に初期化します

于 2011-04-19T01:07:01.740 に答える
1

コンパイラは、CreditPlan が認識されない場合、annualRate は値を持たないと言っています。

ローカル変数 (annualRate、monthlyCharge、および lateFee) を作成するときに、デフォルト値 (0) を割り当てます。

また、クレジット プランが不明な場合は、エラーを表示する必要があります。

于 2011-04-19T01:08:41.820 に答える
0

すべてのコードパスがの値を設定するわけではありませんlateFee。上部にデフォルト値を設定することをお勧めします。

于 2011-04-19T01:08:56.333 に答える
0

ifステートメントの外部に値を割り当てないでください...そして、@ iomaxxが指摘したように、クレジットが0、1、2、または3以外のものである可能性があります。

個別のifステートメントを単一のif/else if / else if/elseに変更してみてください。または、上部にデフォルト値を割り当てます。

于 2011-04-19T01:09:23.553 に答える
0

変数「annualRate」を次のように宣言すると

クラス プログラム {

**static double annualRate;**

public static void Main() {

それを試してみてください..

于 2012-06-20T12:44:02.113 に答える