Kimmy1235
Kimmy1235

Reputation: 917

Having trouble with moving information

I seem to of hit a bit of a snag in a program I am trying to make for school. I am suppose to make a new class to receive data and get a total to send to a new screen. Well I did the same thing we did in class, but the difference is that that was from a text box and there is no text box for the data I need to move this time, so the way I tried gave me an error. Here is what I got so far:

    public StudentSelection()
    {
        InitializeComponent();
    }
    public decimal firstCounter;
    public decimal secondCounter;
    public decimal finalCounter;

    struct StudentScores
    {
        public string StuId;
        public decimal TestOne;
        public decimal TestTwo;
        public decimal Final;  
    }
    StudentScores[] allStudentScores = new StudentScores[10]; 
    // class level array to hold 10 products - read in from a file

    private void StudentSelection_Load(object sender, EventArgs e)
    {
        // read products file into products structure array
        try
        {


            // ALWAYS initialize a structure array before using the array
            //  before adding, changing, etc.
            for (int x = 0; x < 10; x++)
            {
                allStudentScores[x].StuId = "";
                allStudentScores[x].TestOne = 0;
                allStudentScores[x].TestTwo = 0;
                allStudentScores[x].Final = 0;
            }

            int arrayIndex = 0; // needed for incrementing index value of the array
            // when reading file into array

            // now read file into the array after initialization
            StreamReader inputFile;

            string lineofdata; // used to hold each line of data read in from the file
            string[] ProductStringArray = new string[4]; // 6 element string array to hold 
            // each "field" read from every line in file

            inputFile = File.OpenText("StudentScores.txt"); // open for reading

            while (!inputFile.EndOfStream) //keep reading until end of file
            {
                lineofdata = inputFile.ReadLine(); // ReadLine() reads an entire row of data from file
                ProductStringArray = lineofdata.Split(','); //each field is separated by ';'
                allStudentScores[arrayIndex].StuId = ProductStringArray[0]; // add first element of array to first column of allProducts
                allStudentScores[arrayIndex].TestOne = decimal.Parse(ProductStringArray[1]);
                firstCounter += allStudentScores[arrayIndex].TestOne;
                allStudentScores[arrayIndex].TestTwo = decimal.Parse(ProductStringArray[2]);
                secondCounter += allStudentScores[arrayIndex].TestTwo;
                allStudentScores[arrayIndex].Final = decimal.Parse(ProductStringArray[3]);
                finalCounter += allStudentScores[arrayIndex].Final;
                StudentListView.Items.Add(ProductStringArray[0]);
                arrayIndex++; // increment so NEXT row is updated with next read

            }

            //close the file
            inputFile.Close(); 
        }
        catch (Exception anError)
        {
            MessageBox.Show(anError.Message);

        }
    }
    private void NextButton_Click(object sender, EventArgs e)
    {
        decimal firstResult, secondResult, finalResult, stuOne, stuTwo, stuThree;
        string stuName;

        // call the method in our datatier class
        decimal.TryParse(firstCounter, out firstResult);
        decimal.TryParse(secondCounter, out secondResult);
        decimal.TryParse(finalCounter, out finalResult);

        DataTier.AddOurNumbers(firstResult, secondResult, finalResult);
        DataTier.StudentData(stuName, stuOne, stuTwo, stuThree);

        // now hide this window and display a third window with the total
        this.Hide();
        // display third window
        ScoreScreen aScoreScreen = new ScoreScreen();
        aScoreScreen.Show();
    }


}

and my new class

class DataTier
{
    // public static variable available to all windows
    public static decimal firstTotal, secondTotal, finalTotal, stuTestOne, stuTestTwo, stuTestThree;
    // static is not associated with any object

    public static string stuIDCode;

    // create a public method to access from all windows
    public static void AddOurNumbers(decimal NumOne, decimal NumTwo, decimal numThree)
    {
        // devide to get an average
        firstTotal = NumOne / 10;
        secondTotal = NumTwo / 10;
        finalTotal = numThree / 10;
    }

    public static void StudentData(string name, decimal testOne, decimal testTwo, decimal testThree)
    {
        stuIDCode = name;
        stuTestOne = testOne;
        stuTestTwo = testTwo;
        stuTestThree = testThree;
    }
}

The error is at the three decimal.TryParse parts and I have no clue why it is not working except the error says "cannot convert from decimal to string". Any help will be appreciated.

Upvotes: 0

Views: 85

Answers (2)

JLRishe
JLRishe

Reputation: 101748

The decimal.TryParse() method takes a string as its first argument and attempts to convert it to a decimal value. In your case, the variables you are passing to TryParse() are already decimal variables and there is no need to parse them. If you want to just copy class variables to local variables, all you need to do is this:

firstResult = firstCounter;
secondResult = secondCounter;
finalResult = finalCounter;

Or in this particular case, you can just pass the class variables directly into AddOurNumbers:

DataTier.AddOurNumbers(firstCounter, secondCounter, finalCounter);

One thing to note here is that value types, such as decimals and other primitives in C# get copied any time you assign them from one value to another, or pass them into a method. This means that even if the value of firstCounter, secondCounter, or thirdCounter changes after calling DataTier.AddOurNumbers(), the values that your data tier has already recieved will not change.

Upvotes: 0

Aidiakapi
Aidiakapi

Reputation: 6249

Change it from:

    decimal.TryParse(firstCounter, out firstResult);
    decimal.TryParse(secondCounter, out secondResult);
    decimal.TryParse(finalCounter, out finalResult);

    DataTier.AddOurNumbers(firstResult, secondResult, finalResult);

To:

    DataTier.AddOurNumbers(firstCounter, secondCounter, finalCounter);

The problem is that you're trying to call decimal.TryParse(string s, out decimal result) as decimal.TryParse(decimal s, out decimal result).

Your input is already decimal and doesn't require any conversion.


As a side note is that the code

 decimal.TryParse(someString, out someOutputDecimal);

without a proper if statement around it will fail silently (it doesn't inform anything about the failure). In fact the output value is set to 0, and it acts as if no faulty input was received. If the input should always be valid, you should use decimal.Parse(someString) instead. However in some cases defaulting to 0 if the input is invalid, can be the desired behavior.

Upvotes: 2

Related Questions