2012-04-13 5 views
2

Ich habe das Gefühl, dass ich mit dem Debugger immer näher komme, aber ich bin immer noch nicht in der Lage, dies herauszufinden.Probleme haben, etwas zurückzubekommen, aber was der Standardkonstruktor gibt

Ich bin zu Fuß durch den folgenden Code

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)); 

     } 
    } 

} 

} 

ich alles gelöst haben, außer dass die Art nicht von der Steuer geschuldeten Betrag aus irgendeinem Grund jetzt zu sortieren.

+0

Ihr gesendeter Code sollte nicht kompiliert werden, da Sie die Deklaration von 'taxRates' auskommentiert haben, aber Sie verwenden immer noch die (jetzt nicht deklarierte) Variable im letzten Console.WriteLine-Aufruf. – phoog

+0

@programmerNOOB: Sie haben diese Frage zuerst gestellt http://stackoverflow.com/questions/10116706/cant-get-anyything-but-0-from-a-call-to-a-method-to-calculate-a -taxamount und dann diese Frage http://stackoverflow.com/questions/10117669/having-trouble-with-a-method-call-and-getting-a-correct-value-back und in beiden Fällen haben Sie upvoted oder akzeptiert eine Antwort. Vielleicht solltest du das tun, bevor wir Assignment5_2 für dich beenden? – yamen

+0

@phoog, ich weiß, es gab einige Änderungen und zum Zeitpunkt des Kopierens/Einfügens war das nicht korrekt. – programmerNOOB

Antwort

2

Eine beiseite in Bezug auf Taxpayer.GetRates(): die Steuerzahlerklasse sollte nicht für die Festlegung der Steuersätze verantwortlich sein. Wenn Steuerzahler Steuersätze festlegen könnten, wären die Steuersätze höchstwahrscheinlich Null. Es könnte sinnvoller sein, dies in die Klasse Rates zu verschieben.

Diese Antwort auf Ihre Frage zeigt ein Beispiel, das Ihnen helfen soll zu verstehen, wo Sie falsch liegen. Wenn Sie einen spezifischen Vorschlag für Ihren Code wünschen, senden Sie bitte ein vollständiges Programm, das kompiliert. Der Beispielcode, den Sie gepostet haben, wird nicht kompiliert (Fehler: "Der Name 'taxRates' existiert nicht im aktuellen Kontext").

Um Ihre Frage zu beantworten:

How do I instantiate a class so I can use its methods without calling the default constructor?

Wie andere erwähnt haben, müssen Sie einen Verweis auf das neu instanzierte Objekt zu behalten, so können Sie diese Instanz verwenden, wenn Sie die Werte aus den Feldern lesen.

Bedenken Sie:

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

Stattdessen senden Sie das Objekt, das Sie in SetRates() erstellt wurde (und es GetRates nennen() statt). Dann ist es in dem Verfahren UseRates passieren:

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

Hinsichtlich Ihrer editierten Code, haben Sie

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

Jetzt Taxpayer.GetRates() einige Werte zu einer Preise Instanz zuweist, aber es ist nicht das gleiche Preise Instanz, die Sie erstellt mit der Anweisung Rates myTax = new Rates(). Die Anweisung Rates myTax = new Rates()ruft den Standardtarif-Konstruktor auf, und das ist die Instanz, die Sie später in der Methode zur Berechnung der Steuer verwenden! Dies erklärt, warum Ihre Steuer immer mit den Standardwerten berechnet wird.

Die GetRates-Methode arbeitet auf einer anderen Instanz der Kursklasse. Diese andere Instanz wird von einem der Ausdrücke new Rates(... im Hauptteil der GetRates-Methode erstellt. Diese Instanz hat die Raten, die Sie verwenden möchten, aber sie ist im Grunde innerhalb der Methode gefangen. Warum ist es gefangen?Weil Sie die Instanz nur einer lokalen Variablen zuweisen und lokale Variablen nicht außerhalb der Methode zugänglich sind, in der sie deklariert sind.

Es ist ein bisschen wie folgt aus: statt Rates, haben wir Car, und statt GetRates wir haben FillFuelTank. Der Code wird dann die folgenden Schritte ausführen:

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

nun die GetRates() Methode ... ich meine, die FillFuelTank Methode ... tut dies:

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

Sie sehen, was Sie haben erledigt? Sie sind in Ihrem neuen Auto zur Tankstelle gefahren, haben ein zweites Auto mit Benzin drin, und dann sind Sie zurück zum ersten Auto gegangen und sind weggefahren - ohne irgendeinen Brennstoff hinein zu setzen.

Eine Lösung wäre, myTax als ein Argument an die GetRates() Methode zu übergeben; Eine bessere Lösung wäre das Zurückgeben einer Rates-Instanz aus der GetRates()-Methode.

Sie schrieb:

My need for Rates myTax = new Rates(); in main is so that I can call the calculateTax method to do just that. If there is another way to call that method without calling the default constructor, I am all ears or fingers.

Der Ausdruck new Rates() ruft den Standardkonstruktor. So ist die Art und Weise calculateTax ohne Aufruf der Standard-Konstruktor zu nennen, ist die parametrisierte Konstruktor aufzurufen statt:

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

Man könnte sagen, „aber ich habe den parametrisierte Konstruktor in der GetRates Methode aufrufen!“ Und wieder gibt es das Problem, das falsche Auto mit Kraftstoff zu füllen, weil das Rates-Objekt in der GetRates-Methode ein anderes Objekt ist. Sie rufen den parametrisierten Konstruktor für das Objekt auf, das Sie nicht verwenden, und Sie rufen den Standardkonstruktor für das Objekt auf, das Sie verwenden.

+0

Wow, ich denke, das ist jetzt über meinem Kopf. Ich nehme an, diese Methoden in ihren spezifizierten Klassen zu bekommen, wahrscheinlich um es schwieriger zu machen, denke ich. Mein Hauptproblem ist, egal was ich in der Methode getRates auswähle, ich habe immer die Standardwerte der Konstruktoren. – programmerNOOB

+0

@programmerNOOB nehmen Sie jedes dieser Beispiele und durchlaufen Sie sie im Debugger. Das sollte die Dinge klarer machen. Und veröffentlichen Sie ein funktionierendes Beispiel Ihres Codes, damit wir erklären können, was darin passiert. Der von Ihnen gepostete Code wird nicht ausgeführt. Da es sich auch um Hausaufgaben handelt, markieren Sie sie als solche und veröffentlichen Sie die Aufgabe, sodass wir keine Dinge vorschlagen, die die Anforderungen nicht erfüllen. – phoog

+0

Ich habe den Code aktualisiert und wird ausgeführt und fügte auch weitere Informationen hinzu, ich denke mein Problem ist, wenn die Methode getRates() aufgerufen wird, der Konstruktor myRates zeigt mit den Werten, die ich nicht will (Standard) – programmerNOOB

0

Wenn die geschweifte Klammer erreicht ist, verlässt das myRates-Objekt den Gültigkeitsbereich und hört auf zu existieren. Ihre Werte kommen von woanders.

Rates myRates = new Rates(incLimit, lowRate, highRate); 
    //rates.CalculateTax(incLimit); 
} 
+0

also sollte ich es außerhalb der Methode instanziieren und es dann wie myRates.Rates aufrufen (incLimit, lowRate, highRate); aus der Methode heraus? – programmerNOOB

0

I * denke, Ihr Problem ist diese Linie:

Taxpayer.GetRates(); 

Dies ist eine statische Methode, die bedeutet, dass es keine Klasse Membervariablen gesetzt werden. Ich würde erwarten, dass die GetRates() ein Rates-Objekt zurückgibt.

Verwandte Themen