2

デバッガーを使って近づいているような気がしますが、それでもこれを理解することはできません。

私は次のコードを歩いています

namespace Taxes
{

public class Rates
{


    //A class constructor that assigns default values 
    public Rates()
    {
        incLimit = 30000;
        lowTaxRate = .15;
        highTaxRate = .28;
    }
    //A class constructor that takes three parameters to assign input values for limit, low rate and high rate.
    public Rates(int lim, double low, double high)
    {
        incLimit = lim;
        lowTaxRate = low;
        highTaxRate = high;
    }
    //  A CalculateTax method that takes an income parameter and computes the tax as follows:
    public int CalculateTax(int income)
    {
        //determine if the income is above or below the limit and calculate the tax owed based on the correct rate
        int taxOwed;

        if (income < incLimit)
            taxOwed = Convert.ToInt32(income * lowTaxRate); 
        else 
            taxOwed = Convert.ToInt32(income * highTaxRate);

        return taxOwed;
    }


} 

// The Taxpayer class is a comparable class
public class Taxpayer : IComparable
{
    //Use get and set accessors.

    private int taxOwed;

    string SSN
    { set; get; }
    int grossIncome
    { set; get; }
    int TaxOwed {
        get
        {
            return taxOwed;
        }
    }

    int IComparable.CompareTo(Object o)
    {
        int returnVal;
        Taxpayer temp = (Taxpayer)o;
        if (this.taxOwed > temp.taxOwed)
            returnVal = 1;
        else if (this.taxOwed < temp.taxOwed)
            returnVal = -1;
        else returnVal = 0;

        return returnVal;

    }  

    public static Rates GetRates()
    {
        //  Local method data members for income limit, low rate and high rate.
        int incLimit;
        double lowRate;
        double highRate;
        string userInput;
        //Rates myRates = new Rates(incLimit, lowRate, highRate);
        //Rates rates = new Rates();

        //  Prompt the user to enter a selection for either default settings or user input of settings.
        Console.Write("Would you like the default values (D) or would you like to enter the values (E)?:  ");

        // if they want the default values or enter their own
        userInput = (Console.ReadLine());
        if (userInput == "D" || userInput == "d")
        {
            Rates myRates = new Rates();
            return myRates;
            //Rates.Rates();
            //rates.CalculateTax(incLimit);
        }

        else if (userInput == "E" || userInput == "e")
        {
            Console.Write("Please enter the income limit: ");
            incLimit = Convert.ToInt32(Console.ReadLine());
            Console.Write("Please enter the low rate: ");
            lowRate = Convert.ToDouble(Console.ReadLine());
            Console.Write("Please enter the high rate: ");
            highRate = Convert.ToDouble(Console.ReadLine());


            Rates myRates = new Rates(incLimit, lowRate, highRate);
            return myRates;
            //rates.CalculateTax(incLimit);
        }
        else return null;
    }

    static void Main(string[] args)
    {

        Taxpayer[] taxArray = new Taxpayer[5];

        //Rates taxRates = new Rates();
        //  Implement a for-loop that will prompt the user to enter the Social Security Number and gross income.
        for (int x = 0; x < taxArray.Length; ++x)
        {
            taxArray[x] = new Taxpayer();
            Console.Write("Please enter the Social Security Number for taxpayer {0}:  ", x + 1);
            taxArray[x].SSN = Console.ReadLine();

            Console.Write("Please enter the gross income for taxpayer {0}:  ", x + 1);
            taxArray[x].grossIncome = Convert.ToInt32(Console.ReadLine());
            //taxArray[x].taxOwed = taxRates.CalculateTax(taxArray[x].grossIncome);

        }

        Rates myRate = Taxpayer.GetRates();
        //Taxpayer.GetRates();

        //  Implement a for-loop that will display each object as formatted taxpayer SSN, income and calculated tax.
        for (int i = 0; i < taxArray.Length; ++i)
        {
            Console.WriteLine("Taxpayer # {0} SSN: {1}, Income is {2:c}, Tax is {3:c}", i + 1, taxArray[i].SSN, taxArray[i].grossIncome, myRate.CalculateTax(taxArray[i].grossIncome));//taxArray[i].taxOwed);

        } 
        //  Implement a for-loop that will sort the five objects in order by the amount of tax owed 
        Array.Sort(taxArray);
        Console.WriteLine("Sorted by tax owed");
        for (int i = 0; i < taxArray.Length; ++i)
        {
            //double taxes = myTax.CalculateTax(taxArray[i].grossIncome);
            Console.WriteLine("Taxpayer # {0} SSN: {1}, Income is {2:c}, Tax is {3:c}", i + 1, taxArray[i].SSN, taxArray[i].grossIncome, myRate.CalculateTax(taxArray[i].grossIncome));

        }
    }  

} 

} 

なんらかの理由で未払額でソートされていないことを除けば、すべて解決しました。

4

3 に答える 3

2

余談Taxpayer.GetRates()ですが、納税者クラスは税率を決定する責任を負わないはずです。納税者が税率を決定できれば、税率はおそらくゼロになるでしょう。それをRatesクラスに移す方が理にかなっているかもしれません。

あなたの質問に対するこの答えは、あなたがどこで間違っているのかを理解するのに役立つはずの例を示しています。コードに関連する具体的な提案が必要な場合は、コンパイルする完全なプログラムを投稿してください。投稿したサンプルコードはコンパイルされません(エラー:「名前'taxRates'は現在のコンテキストに存在しません」)。

あなたの質問に答えるには:

デフォルトのコンストラクターを呼び出さずにそのメソッドを使用できるように、クラスをインスタンス化するにはどうすればよいですか?

他の人が指摘しているように、新しくインスタンス化されたオブジェクトへの参照を保持する必要があるため、フィールドから値を読み取るときにそのインスタンスを使用できます。

検討:

void SetRates()
{
    Rates rates = new Rates(10000, 0.3, 0.4);
}

void UseRates(Taxpayer taxpayer)
{
    taxpayer.Tax = new Rates().CalculateTax(taxpayer.Income);
}

void Main()
{
    SetRates();                              // creates an object and throws it away
    Taxpayer taxpayer = new Taxpayer(20000);
    UseRates(taxpayer);                      // creates a new object with default values
    Console.WriteLine(taxpayer.Tax);
}

代わりに、SetRates()で作成したオブジェクトを返します(代わりにGetRates()と呼びます)。次に、それをUseRatesメソッドに渡します。

Rates GetRates()
{
    return new Rates(10000, 0.3, 0.4);
}

void UseRates(Taxpayer taxpayer, Rates rates)
{
    taxpayer.Tax = rates.CalculateTax(taxpayer.Income);
}

void Main()
{
    Rates rates = GetRates();
    Taxpayer taxpayer = new Taxpayer(20000);
    UseRates(taxpayer, rates);
    Console.WriteLine(taxpayer.Tax);
}

編集したコードに関しては、

Rates myTax = new Rates();
Taxpayer.GetRates();

ここTaxpayer.GetRates()で、Ratesインスタンスにいくつかの値を割り当てますが、ステートメントで作成したRatesインスタンスとは異なりますRates myTax = new Rates() このステートメントRates myTax = new Rates() はデフォルトのRatesコンストラクターを呼び出します。これは、後で税金を計算するメソッドで使用するインスタンスです。 これは、税金が常にデフォルト値で計算される理由を説明しています。

GetRatesメソッドは、Ratesクラスの別のインスタンスで動作します。その異なるインスタンスはnew Rates(...、GetRatesメソッドの本体にある式の1つによって作成されます。そのインスタンスには使用したいレートがありますが、基本的にはメソッド内に閉じ込められています。なぜ閉じ込められているのですか?インスタンスをローカル変数に割り当てるだけであり、ローカル変数は、それらが宣言されているメソッドの外部からはアクセスできないためです。

これは少し似ています:の代わりにRates、がありCar、の代わりに。GetRatesがありFillFuelTankます。次に、コードは次のことを実行します。

Get a new car          //Rates myTax = new Rates();
Go to the gas station  //Taxpayer.GetRates();

さて、GetRates()メソッド...つまり、FillFuelTankメソッド...はこれを行います:

Get a new car with fuel in it //Rates myRates = new Rates(incLimit, lowRate, highRate)

何をしたかわかりますか?あなたは新しい車でガソリンスタンドに車で行き、燃料が入った2台目の車を手に入れました。その後、最初の車に戻って、燃料を入れずに車を走らせました。

myTaxこれに対する1つの解決策は、メソッドへの引数として渡すことGetRates()です。より良い解決策は、GetRates()メソッドからRatesインスタンスを返すことです。

あなたが書いた:

レートの必要性myTax=new Rate(); 主に、calculateTaxメソッドを呼び出してそれを実行できるようにするためです。デフォルトのコンストラクターを呼び出さずにそのメソッドを呼び出す別の方法がある場合、私はすべて耳か指です。

この式new Rates()はデフォルトのコンストラクターを呼び出します。したがって、calculateTaxデフォルトのコンストラクターを呼び出さずに呼び出す方法は、代わりにパラメーター化されたコンストラクターを呼び出すことです。

Rates rates = new Rates(limit, lowRate, highRate);
double tax = rates.CalculateTax(taxpayer.Income);

「しかし、GetRatesメソッドでパラメーター化されたコンストラクターを呼び出しました!」と言うかもしれません。また、GetRatesメソッドのRatesオブジェクトは別のオブジェクトであるため、間違った車に燃料を充填するという問題があります。使用しないオブジェクトでパラメーター化されたコンストラクターを呼び出し、使用するオブジェクトでデフォルトのコンストラクターを呼び出します。

于 2012-04-13T04:18:23.383 に答える
0

中括弧に達すると、myRatesオブジェクトはスコープ外になり、存在しなくなります。あなたの価値観はどこかから来ています。

   Rates myRates = new Rates(incLimit, lowRate, highRate);
    //rates.CalculateTax(incLimit);
}
于 2012-04-13T04:01:24.957 に答える
0

私は*あなたの問題はこの行だと思います:

Taxpayer.GetRates();

これは静的メソッドであり、クラスメンバー変数を設定しないことを意味します。GetRates()がRatesオブジェクトを返すことを期待します。

于 2012-04-13T04:04:03.903 に答える