0

Im making a basic CSV Reader. Im sepparating the header from the contents using header and data. Now, my lists contain data of the type person.:

        public class person
{
    public int id;
    public string name;
    public int age;

    public person(string id, string name, string age)
    {
        try
        {
            this.id = Convert.ToInt32(id);
            this.name = name;
            this.age = Convert.ToInt32(age);
        }
        catch (FormatException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    public string ToString()
    {
        return $"{id}, {name}, {age}";
    }
}

Now id like to take the type data and make a type person that stores the information. Right now i am trying to use IEnumerable<> for everything since many comments here say that its better for memory management. Now, since it behaves a little different then List<T> I'm having issue making a type that stores persons. Im having errors left and right using IEnumerable so i couldnt be bothered to write my shitty code down.

var data = file.Skip(1).Select(p => p.Split(';'));
IEnumerable<person> listofperson;

My question is, how can i make this work using IEnumerable<>? Or should i even care and rather go for List<>?

3
  • 1
    If you want an interface that supports adding, then maybe consider ICollection<T>? Commented May 3, 2022 at 9:52
  • Use a type internal to your csv reader class that supports changing like List<T>. If you don't want that an external user to that class then change the resulting List then surface that list just an IEnumerable<T>. Commented May 3, 2022 at 10:18
  • Unless it's for learning-purposes, there is no reason to roll your own CSV reader. There are plenty of open source CSV readers about. Commented May 3, 2022 at 10:22

2 Answers 2

3

There is the IEnumerable.Append. This is great if you want to tack on one additional item to a large list without making a full copy, but it is not appropriate to use when adding many items.

I would probably suggest using an iterator block

public IEnumerable<Person> GetData(){
   ...
   var lines = file.Skip(1);
   foreach(var line in lines){
      var cells = line.Split(';');
      var person = new Person(...);
      yield return person;  
   }
}

This is a easy and compact way to write a lazy reader that processes data as it is needed. But be aware that this parsing will be done each time the IEnumerable is iterated over. So in many cases the first thing you do is convert it to a list anyway.

I would be careful about claims about memory management. If you are processing huge files, some kind of streaming solution like this can indeed be critical, but you need to be really careful so that you never need to keep all of the file in memory. However, when processing small files it might very well be more efficient to do all the processing in one go. Or do something in between, like processing chunks of data. It really depends on what your use case is and what the memory and performance requirements are.

Sign up to request clarification or add additional context in comments.

Comments

1

IEnumerable<T> is just an interface, not an implementation. If you look at its definition, it only supports the ability to 'enumerate'. You're looking for an interface, and an underlying type, that supports the ability to add types to some kind of collection. If you look at ICollection<T> you'll find it builds on IEnumerable<T>'s enumeration abilities, adding support for managing the content of a collection. The typical type used for this purpose is List<T>. I would start there, populating your List<Person> with objects. Once you have this list of Person, you can use the interfaces List<T> implements to control how it's used. For example, if you only want to offer enumeration support on your List<Person>, you can cast it to IEnumerable<Person>, narrowing the focus.

var myPeople = new List<Person>();

/// populate the list
myPeople.Add(new Person());

/// provide 'focussed' interface to underlying type
IEnumerable<Person> enumerablePeople = myPeople;

There are other types that implement ICollection<T> with varying specialities, however, List<T> is probably the simplest starting point for what you need.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.