none
C# Adding data from a class to List and saving the data to a File RRS feed

  • Question

  • Hi every one,

    For a couple of hours i have been struggling with this piece of code:

    ==============================================================================  

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
            public interface Item 
            {
                void printData();
            }
    
            public class Product : Item
            {
                public string name;
                public int quantity;
    
                public void printData() { }
            }
    
            public class Milk : Product
            {
                public string name = "Milk";
                public int quantity = 2;
                public int cal;
                public int protein;
                public string softness;
    
                public void printData()
                {
                    Console.WriteLine("{0} has {1} cal and {2} protein", name, cal, protein);
                    Console.WriteLine("Softness = " + softness);
                }
            }
    
            public class Potato : Product
            {
                public string name = "Potato";
                public int quantity = 5;
                public int cal;
                public int protein;
                public string hardness;
    
                public void printData()
                {
                    Console.WriteLine("{0} has {1} cal and {2} protein", name, cal, protein);
                    Console.WriteLine("Hardness = " + hardness);
                }
            }
    
            static void Main(string[] args)
            {
                Product product = new Product();
    
                Milk milk = new Milk();
                milk.protein = 8;
                milk.cal = 350;
                milk.softness = "Soft";
                product.printData();
                milk.printData();
    
                Potato potato = new Potato();
                potato.protein = 12;
                potato.cal = 25;
                potato.hardness = "Hard";
                product.printData();
                potato.printData();
    
                List<string> items = new List<string>();
                items.Add();
    
                foreach(object Item in items)
                {
                    Console.WriteLine();
                    //Console.WriteLine(new Potato());
                }
    
                /*foreach (string item in items)
                {
                    Console.WriteLine(item);
                }
    
                File.WriteAllText("Text.txt",items);*/
    
                Console.ReadLine();
            }
        }
    }

    ==============================================================================

    So i want to get the data from name, quantity, cal, protein, hardness and softness and save it to a file.

    Basically that's a homework i was given which i never made in time, and i was revisiting old stuff and found that.

    ==============================================================================

    The homework says:

    Describe with classes two items of your choice.

    Expand one with his successor.

    Write an interface with one method to support all three classes.

    Create a list of the interface and save one of the three classes in it.

    Use foreach to browse the list items and invoke the common method.

    Save the object to a file and read them back.

    ==============================================================================

    I would also like to see how some one else would do it! :)

    If you have time, of course . :)

    And if you can give me a good explanation i will be really grateful!

    The interface is a must! Just cause i want to learn how to use them.

    Any tips are welcomed. :)

    I am a beginner so please don't bully me too much! :P

    Monday, October 8, 2018 8:37 PM

Answers

  • Greetings Frank.

    Your code is a bit of a mess in a number of ways (which probably doesn't surprise you).

    Firstly, by extremely strong convention, interfaces have a capital 'I' prefixed to their name even if the name already starts with an 'I'. Thus your interface should be IItems.

    Secondly, your two classes are virtually identical, and the differences are not sufficient for the classes to be considered different. This is a bit of a difficult concept to explain for a beginner, but here goes.

    Instead of one class having a string called "hardness" and the other having a string called "softness", each could have a string called "hardOrSoft". Then, in the PrintData method, you could print that string, which would make the two methods identical.

    Next, you are hard-coding the name and quantity in the classes, even though those things are public and can therefore be changed outside the class. This is a no-no. Public data should not be hard-coded like that. Instead, they can be set when the objects are instantiated.

    So, given all that, there is no clear reason for separate Milk and Potato classes. Which rather obviates the need for an interface, but we can still use one to illustrate the point.

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp6
    {
       class Program
       {
          public interface IItem
          {
             void printData();
          }
    
          public class Product : IItem
          {
             string Name;
             int Quantity;
             int Cal;
             int Protein;
             string HardOrSoft;
    
             public Product(string name, int quantity, int cal, int protein, string hardOrSoft)
             {
                Name = name;
                Quantity = quantity;
                Cal = cal;
                Protein = protein;
                HardOrSoft = hardOrSoft;
             }
    
    
             public void printData()
             {
                Console.WriteLine("{0} has {1} cal and {2} protein", Name, Cal, Protein);
                Console.WriteLine("Hard or Soft = " + HardOrSoft);
             }
          }
    
    
          static void Main(string[] args)
          {
             List<IItem> items = new List<IItem>();
             Product product = new Product("Milk", 2, 350, 8, "Soft");
             items.Add(product);
    
             product = new Product("Potato", 5, 25, 12, "Hard");
             items.Add(product);
    
             foreach (IItem Item in items)
             {
                Item.printData();
             }
    
             Console.ReadLine();
          }
       }
    
    }


    Edit : And before anyone else points it out, (ritehere, are you listening?) I am aware there are many ways the code I posted could be improved. For example, the HardOrSoft property should really be an enum not a string, to make it impossible to enter a value that's not valid. I was trying to keep it simple for a beginner.
    Monday, October 8, 2018 11:11 PM

All replies

  • See the following which is one of many ways to complete the task.

    https://www.techcoil.com/blog/how-to-save-and-load-objects-to-and-from-file-in-c/


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Monday, October 8, 2018 10:28 PM
    Moderator
  • Greetings Frank.

    Your code is a bit of a mess in a number of ways (which probably doesn't surprise you).

    Firstly, by extremely strong convention, interfaces have a capital 'I' prefixed to their name even if the name already starts with an 'I'. Thus your interface should be IItems.

    Secondly, your two classes are virtually identical, and the differences are not sufficient for the classes to be considered different. This is a bit of a difficult concept to explain for a beginner, but here goes.

    Instead of one class having a string called "hardness" and the other having a string called "softness", each could have a string called "hardOrSoft". Then, in the PrintData method, you could print that string, which would make the two methods identical.

    Next, you are hard-coding the name and quantity in the classes, even though those things are public and can therefore be changed outside the class. This is a no-no. Public data should not be hard-coded like that. Instead, they can be set when the objects are instantiated.

    So, given all that, there is no clear reason for separate Milk and Potato classes. Which rather obviates the need for an interface, but we can still use one to illustrate the point.

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp6
    {
       class Program
       {
          public interface IItem
          {
             void printData();
          }
    
          public class Product : IItem
          {
             string Name;
             int Quantity;
             int Cal;
             int Protein;
             string HardOrSoft;
    
             public Product(string name, int quantity, int cal, int protein, string hardOrSoft)
             {
                Name = name;
                Quantity = quantity;
                Cal = cal;
                Protein = protein;
                HardOrSoft = hardOrSoft;
             }
    
    
             public void printData()
             {
                Console.WriteLine("{0} has {1} cal and {2} protein", Name, Cal, Protein);
                Console.WriteLine("Hard or Soft = " + HardOrSoft);
             }
          }
    
    
          static void Main(string[] args)
          {
             List<IItem> items = new List<IItem>();
             Product product = new Product("Milk", 2, 350, 8, "Soft");
             items.Add(product);
    
             product = new Product("Potato", 5, 25, 12, "Hard");
             items.Add(product);
    
             foreach (IItem Item in items)
             {
                Item.printData();
             }
    
             Console.ReadLine();
          }
       }
    
    }


    Edit : And before anyone else points it out, (ritehere, are you listening?) I am aware there are many ways the code I posted could be improved. For example, the HardOrSoft property should really be an enum not a string, to make it impossible to enter a value that's not valid. I was trying to keep it simple for a beginner.
    Monday, October 8, 2018 11:11 PM
  • Thank you for the fast response!

    It was helpful!

    I will take a note of this and improve!

    I want to ask...how can i extend class Product with two subclasses? I mean i know how but what are the requirements for a subclass to be needed?

    Thank you again for the friendly explanation! 

    Have a nice day!

    Tuesday, October 9, 2018 8:54 AM
  • Greetings again Frank.

    If you want to know about standard techniques for developing class structures, I am definitely not the person to ask. To me, it's all an art rather than a science, and it relies a lot on instinct. But I'll have a go at explaining as best I can

    Generally, 'subclasses' as you have called them, should have some things in common but others that are distinctly different. What I mean by 'distinctly different' is a bit nebulous, but it basically means 'enough to make them different types (classes) of objects'. Which is still nebulous.

    To use your above example, you wouldn't usually write a whole class for potatoes and another one for milk. They are very different objects, but not different classes of objects. A class for both of them might be Foods. A class for the potatoes alone might be Vegetables, and a class for the milk might be Drinks. But splitting Foods into Vegetables and Drinks is only necessary if those two classes require different properties and/or methods. For example, Vegetables might require a weight, while Drinks might require a volume.

    Anyway, forgetting about the Vegetables and Drinks for the moment and concentrating on your actual assignment ... 

    I would derive two classes from Product such as Food and Cleaner. These two things have in common what all Products have in common - buying price, selling price, perhaps a use-by date - and not much else. Foods would have nutritional information like vitamins and sugar, while the Cleaners would have things like what surface they are used to clean (bathroom, kitchen, carpet, etc.), toxicity, and so on. So the base class would have the things in common, and the derived classes everything else. And both derived classes would have a PrintData method, as defined in the interface, which could print completely different info.

    I hope that helps and doesn't just confuse things.


    • Edited by Ante Meridian Tuesday, October 9, 2018 10:59 PM typo.
    Tuesday, October 9, 2018 10:53 PM