Ian Carpenter
Ian Carpenter

Reputation: 8626

Calling a method that expects an array of objects

I'm learning C# and have written a console program to save an an array of high scores to a file. Although the program works, how I have got it to work is making me feel uneasy and feels more of a hack than a solution so I was looking for guidance on how I should have written it.

What I am currently doing within the Main method is:

  1. Declaring an array of highscore objects
  2. Initialising them
  3. Assigning some values to the array.

I am happy with what I have done up until now, it's the following two steps that make me uneasy

  1. I then declare another HighScore object
  2. I use this object to pass the array of highscores to the SaveHighScores method.

Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace HighScore
{
    class HighScore
    {
        public string Name { get; set; }

        public int Score { get; set; }

        public void SaveHighScores(HighScore[] highScores)
        {
            string allHighScoresText = "";

            foreach (HighScore score in highScores)
            { 
                allHighScoresText += $"{score.Name},{score.Score}" + Environment.NewLine;
            }

            File.WriteAllText("C:/Temp/highscores.csv", allHighScoresText);
        }

        static void Main(string[] args)
        {
            HighScore[] highScore = new HighScore[2];

            for (int i = 0; i < highScore.Length; i++)
            {
                highScore[i] = new HighScore();
            }

            highScore[0].Name = "A";
            highScore[0].Score = 100;

            highScore[1].Name = "B";
            highScore[1].Score = 200;

            // are the following two lines correct or am I missing something?
            HighScore hs = new HighScore();

            hs.SaveHighScores(highScore);

        }
    }
}

Upvotes: 2

Views: 145

Answers (2)

Steve
Steve

Reputation: 216273

I prefer to split the representation of your data from the actions that you perform on this data. So I would go for two classes, one for the Data and one for the Save/Load and other business logic

public class HighScore
{
    public string Name { get; set; }
    public int Score { get; set; }
}

// This class handles the core work to persist your data on the storage medium
// The class is static so you don't need to declare instances and use directly the methods available.
public static class Repo_HighScore
{
    // For simplicity, no error Handling but, for a robust implementation,
    // error handling is required
    public static bool SaveHighScores(HighScore[] highScores)
    {
        StringBuilder allHighScoresText = new StringBuilder();
        foreach (HighScore score in highScores)
            allHighScoresText.AppendLine($"{score.Name},{score.Score}"); 

        File.WriteAllText("C:/Temp/highscores.csv", allHighScoresText.ToString());
    }
    public static HighScore[] LoadHighScores()
    {
        List<HighScore> hs = new List<HighScore>();
        foreach(string line in File.ReadLines("C:/Temp/highscores.csv"))
        {
           string[] parts = line.Split(',');
           HighScore temp = new HighScore() 
                { Name = parts[0], Score = Convert.ToInt32(parts[1])};
           hs.Add(temp);
        }
        return hs.ToArray();
    }
}

Upvotes: 3

adv12
adv12

Reputation: 8551

Make SaveHighScores static and you won't need an instance of HighScore to call it. (You can call it directly as HighScore.SaveHighScores())

Upvotes: 6

Related Questions