-1

Here is my code -

class Appointments:IAppointments
{
    private readonly IList<IAppointment> _list = new List<IAppointment>(); 

    public Appointments()
    {

    }

    public bool Load()
    {
        throw new NotImplementedException();
    }

    public bool Save()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<IAppointment> GetAppointmentsOnDate(DateTime date)
    {
        throw new NotImplementedException();
    }

    public int IndexOf(IAppointment item)
    {
        return _list.IndexOf(item);
    }

    public void Insert(int index, IAppointment item)
    {
        _list.Insert(index, item);
    }

    public void RemoveAt(int index)
    {
        _list.RemoveAt(index);
    }

    public IAppointment this[int index]
    {
        get
        {
            return _list[index];
        }
        set
        {
            _list[index] = value;
        }
    }

    public void Add(IAppointment item)
    {
        _list.Add(item);
    }

    public void Clear()
    {
        _list.Clear();
    }

    public bool Contains(IAppointment item)
    {
        return _list.Contains(item);
    }

    public void CopyTo(IAppointment[] array, int arrayIndex)
    {
        _list.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return _list.Count; }
    }

    public bool IsReadOnly
    {
        get { return _list.IsReadOnly; }
    }

    public bool Remove(IAppointment item)
    {
        return _list.Remove(item);
    }

    public IEnumerator<IAppointment> GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        foreach (IAppointment item in _list)
        {
            if (item == null)
            {
                break;
            }

            yield return item;
        }

I would like help on how to do the load and save methods. The save method needs to save to a text file. The load method needs to load from a txt file.

IAppointment interface -

 namespace Calendar
    {
        public interface IAppointment
        {
            DateTime Start { get; }
            int Length { get; }
            string DisplayableDescription { get; }
            bool OccursOnDate(DateTime date);
        }
    }

The website is complaining that this is mostly code so I am going to write this pointless sentence until it hopefully goes away. Thank you for your patience.

Ely
  • 51
  • 7
  • 1
    So basically you want to serialise and deserialise the class? – David Pilkington Jun 04 '15 at 12:06
  • You need a public list properties. Don't see any!!! – jdweng Jun 04 '15 at 12:17
  • I have added my complete class. It didn't seem to like it before – Ely Jun 04 '15 at 12:20
  • Can you show the definition of `IAppointment`? If it's an interface (the `I` prefix suggests so), then what concrete classes implement it? Can you show their code too? – Pieter Witvoet Jun 04 '15 at 13:50
  • Thank you. I have added the code – Ely Jun 04 '15 at 13:59
  • Saving objects to a file involves translating the in-memory objects to a string or array of bytes - which is called serializing. If you're just starting out, simply writing all fields as strings to a file, each on a separate line, would be sufficient. Reading them back involves translating these strings back into objects, using `DateTime.Parse`, `int.Parse`, etc. Alternately, you can use a JSON or XML library for a more structured approach, or an actual serialization library. Do note that you'll need a concrete implementation of `IAppointment` - you can't instantiate an interface. – Pieter Witvoet Jun 04 '15 at 15:05
  • So my list should be Appointment (the class) and not IAppointment (the interface)? I am totally confused – Ely Jun 04 '15 at 15:20
  • If you have an `Appointment` class that implements the `IAppointment` interface, then a `List` can hold `Appointment` objects - but if I wrote a `SecretAppointment` class that also implements `IAppointment`, then I could also add such objects to that list. No big deal, except that now you need to know which class to use when reading appointments back from a file. I would keep things simple by removing the `IAppointment` interface and just using the `Appointment` class - less stuff to worry about. – Pieter Witvoet Jun 04 '15 at 20:25
  • I can't remove the IAppointment interface because it is part of my assignment spec. I have an IAppointment interface > Appointment class and the a recurring Appointment subclass. Lord knows how the ReccurringAppoint ment class will be saved to the list – Ely Jun 04 '15 at 22:05
  • Can you change the interface to a class? – jdweng Jun 05 '15 at 11:57
  • No I'm afraid the interfaces can't be changed. I'am hoping I have created the list of the correct type to store the appointments in. – Ely Jun 05 '15 at 16:39

3 Answers3

0

This is the serialization code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Calendar
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            //add to appointments to object below
            Appointments appointments = new Appointments()
            {
                appointments = new List<Appointment>() {
                    new Appointment(){ start = DateTime.Today, length = 2, displayableDescription = "Meeting wiith Joe", occursOnDate = true},
                    new Appointment(){ start = DateTime.Today.AddDays(2), length = 3, displayableDescription = "Meeting wiith Jane", occursOnDate = false}
                }
            };


            //use this code for writing
            XmlSerializer serializer = new XmlSerializer(typeof(Appointments));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, appointments);
            writer.Flush();
            writer.Close();
            writer.Dispose();

            //use this code for reading
            XmlSerializer xs = new XmlSerializer(typeof(Appointments));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            Appointments newAppointments = (Appointments)xs.Deserialize(reader);

        }
    }
    [XmlRoot("appointments")]
    public class Appointments
    {
        [XmlElement("appointment")]
        public List<Appointment> appointments { get; set; }

    }
    [XmlRoot("appointment")]
    public class Appointment
    {
        [XmlElement("start")]
        public DateTime start { get; set; }
        [XmlElement("length")]
        public int length { get; set; }
        [XmlElement("displayableDescription")]
        public string displayableDescription { get; set; }
        [XmlElement("occursOnDate")]
        public bool occursOnDate { get; set; }
    }


}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Serialization only looks at public variables (not methods) so you can combine the classes above with your existing classes. – jdweng Jun 05 '15 at 09:48
0

I would just use Json as it's much cleaner and smaller than XML. So for example:

private IList<IAppointment> _list {get; set;}

public Appointments()
{
    _list = Load() ?? new List<IAppointment>();
}

public List<IAppointment> Load()
{
    try
    {
        var json = File.ReadAllText(".Appointments.json");
        var list = JsonConvert.DeserializeObject<List<IAppointment>>(json);
        return list;
    }
    catch
    {
        return null;
    }
}

public bool Save()
{
    try
    {
        var json = JsonConvert.SerializeObject(_list);
        File.WriteAllText(".Appointments.json",json);
        return true;
    }
    catch
    {
        return false;
    }
}

Don't forget to add Newtonsoft.Json to your project via Nuget:

To install Json.NET, run the following command in the Package Manager Console

PM> Install-Package Newtonsoft.Json -Version 6.0.8
Charles
  • 91
  • 6
0

I combined my code into your classes. Will need to be debugged but should help you understand serialization better.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace Calendar
{
    class Program
    {

        static void Main(string[] args)
        {
        }
    }
    public class IAppointments : IAppointment
    {
        public DateTime Start { get; set; }
        public int Length { get; set; }
        public string DisplayableDescription { get; set; }
        public bool OccursOnDate(DateTime date)
        {
            return true;
        }
    }
    class Appointments : IAppointments
    {
        const string FILENAME = @"c:\temp\test.xml";
        private readonly IList<IAppointment> _list = new List<IAppointment>();

        public void Add(IAppointment item)
        {
            _list.Add(item);
        }

        public bool Load()
        {
            XmlSerializer xs = new XmlSerializer(typeof(c_Appointments));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            c_Appointments newAppointments = (c_Appointments)xs.Deserialize(reader);

            foreach (Appointment appointment in newAppointments.appointments)
            {
                IAppointments newAppointment = new IAppointments();
                newAppointment.Start = appointment.start;
                newAppointment.Length = appointment.length;
                newAppointment.DisplayableDescription = appointment.displayableDescription;
                this.Add(newAppointment);
            }

            return true;

        }

        public bool Save()
        {
             c_Appointments appointments = new c_Appointments();
             appointments.appointments = new List<Appointment>();
             foreach (IAppointment iAppointment in _list)
             {
                Appointment  newAppoint = new Appointment();
                appointments.appointments.Add(newAppoint);
                newAppoint = (Appointment)iAppointment;
             }

            XmlSerializer serializer = new XmlSerializer(typeof(c_Appointments));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, appointments);
            writer.Flush();
            writer.Close();
            writer.Dispose();

            return true;
        }
    }
    public interface IAppointment
    {
        DateTime Start { get; }
        int Length { get; }
        string DisplayableDescription { get; }
        bool OccursOnDate(DateTime date);
    }
    [XmlRoot("appointments")]
    public class c_Appointments
    {
        [XmlElement("appointment")]
        public List<Appointment> appointments { get; set; }

    }
    [XmlRoot("appointment")]
    public class Appointment
    {
        [XmlElement("start")]
        public DateTime start { get; set; }
        [XmlElement("length")]
        public int length { get; set; }
        [XmlElement("displayableDescription")]
        public string displayableDescription { get; set; }
    }

}
​
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • The classes seem fairly differrent. Appointments inherits from IList so I have written those methods in there – Ely Jun 06 '15 at 10:33
  • Do I need to write a new class called 'public class c_Appointments'? I'm not quite sure what that is doing. Thanks – Ely Jun 06 '15 at 10:49
  • XML has a single root tag. Your appointments will be a list of appointments so they need to be wrapped in a root tag (appointments). Run my solution where I wrote 2 appointments to an XML. See code with appointments = new List() { new Appointment(){ start = DateTime.Today, length = 2, displayableDescription = "Meeting wiith Joe", occursOnDate = true}, new Appointment(){ start = DateTime.Today.AddDays(2), length = 3, displayableDescription = "Meeting wiith Jane", occursOnDate = false} } – jdweng Jun 06 '15 at 11:06
  • I created some dummy classes just to remove the compiler errors. Use you complete classes. I just wrote the two methods Load() & Save() and included my two serialization classes. – jdweng Jun 06 '15 at 11:10
  • So I meed the c_Appointments class. I'm sorry I really don't have a good enough grasp of c# to understand a lot of this – Ely Jun 06 '15 at 11:33
  • In the Load() method. I cannot creat an instance of IAppointment because it is an interface. Serialisation seems so complicated that it is really difficult to work out any problems myself – Ely Jun 06 '15 at 11:55
  • That is why I had IAppointments inherit IAppointment: public class IAppointments : IAppointment. It is not the serialization that is hard, it is the VS interfaces. Not sure what restrictions your teacher gave you, but some of the issues is the teacher not the code. – jdweng Jun 06 '15 at 12:18