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将其移入课堂可能更有意义。

This answer to your question显示了一个示例,可以帮助您了解哪里出错了。如果您想要与您的代码相关的具体建议,请发布一个完整的编译程序。您发布的示例代码无法编译(错误:“名称 '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 方法主体中的表达式之一创建的。该实例具有您想要使用的速率,但它基本上被困在方法中。为什么会被困?因为您只将实例分配给局部变量,而局部变量在声明它们的方法之外是不可访问的。

有点像这样: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)

你看到你做了什么吗?你开着新车开到加油站,又买了第二辆车,里面有燃料,然后你又回到第一辆车上,开车离开了——没有加任何燃料。

一种解决方案是myTax作为参数传递给GetRates()方法;GetRates()更好的解决方案是从该方法返回一个 Rates 实例。

你写了:

我需要费率 myTax = new Rates(); 主要是这样我就可以调用 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 回答