-1

very new to c# here and following tutorials on PluralSight.

i have the following files (Classes i think ?)

Program.cs

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

namespace Customers
{
    class Program
    {
        static void Main(string[] args)
        {
            CustomerList customers = new CustomerList();

            customers.AddCustomer("Apple");
            customers.AddCustomer("Microsoft");
        }
    }
}

And CustomerList.cs

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

namespace Customers
{
    public class CustomerList
    {
        public CustomerList()
        {
            customers = new List<string>();
        }

        public void AddCustomer(string customer)
        {
            customers.Add(customer);
        }

        private List<String> customers;
    }
}

The snag i'm hitting is i just want to list out the items within the list and doing so is stumping me. I did try to use a foreach statement as follows.

      foreach (string customer in customers)
        {
            Console.WriteLine(customer);
        }

from within Program.cs but i'm unable to do so as it states

"foreach statement cannot operate on variables of type 'CustomerList' because 'CustomerList' does not contain a public instance definition for 'GetEnumerator'"

However if i keep all my code within Program.cs and use the following i am able to write out each item within list.

private List<string> customers;

static void Main(string[] args)
{
    customers = new List<String>();
    AddCustomers(customers);

    foreach(string customer in customers) {

         Console.WriteLine(customer);
    }


}

private void AddCustomers(List<string> customers)
    {
        customers.Add("Apple");
        customers.Add("Microsoft");
    }

Like i say, very new, so please go easy one me.

Chris Catignani
  • 5,040
  • 16
  • 42
  • 49
Matt Leyland
  • 2,149
  • 3
  • 15
  • 16

2 Answers2

3

Try implementing the IEnumerable interface in your CustomerList class. By doing this, you have to add the method GetEnumerator() and that will allow you to iterate through your list of strings. Implement the interface like below (notice the : IEnumerable in the class definition):

public class CustomerList : IEnumerable 
{
    ... // Your current code \\ ...

    public IEnumerator GetEnumerator()
    {
        return customers.GetEnumerator();
    }
}
dvo
  • 2,113
  • 1
  • 8
  • 19
  • 1
    But this is, in my opinion, not the desired behavior. – bolkay May 28 '19 at 16:48
  • @bolkay I disagree. Based off his explanation, and sample code he attempted - I believe this is the desired behavior. It gives him the output he is looking for by calling his object in a foreach. It may not be the _best_ solution and definitely isn't the only solution. But I do believe it is _a_ solution that gives desired behavior. – dvo May 28 '19 at 16:52
  • 1
    Just make it.. Public List customers..no need to implement IEnumerable..here List already implemented it – SUNIL DHAPPADHULE May 28 '19 at 16:52
  • @dvo i complelety agree with you.I believe in keep it simple and minimum code change. – SUNIL DHAPPADHULE May 28 '19 at 17:10
2

You need to begin by examining your CustomList definition and the instance customers. The instance customers, is not a collection and hence cannot be enumerated as the error description says. But rather, it is an instance of CustomerList, which has a property called customer.

The property customer is a collection of Strings and can be enumerated, however, in your case, you have declared it as private.

So, the first change you need to do is to make it public property. Please note I have not made the variable public, but rather made it Public Property. You can learn more on properties here

public List<String> customers {get;set;}

And then, in your foreach you can do as following.

foreach (string customer in customers.customers)
{
    Console.WriteLine(customer);
}

This is however, changes that might be needed to make your existing code working. But, if you were to rewrite the entire code , you have couple of options.

a) Could do away with CustomerList class and use List directly.

var customers = new List<string>();
customers.Add("Apple");

b) Use the CustomerList class but use the public property Customers to add to the list directly

public class CustomerList
{
    public CustomerList()
    {
        customers = new List<string>();
    }

    public List<String> Customers;
}

Client Code

CustomerList customers = new CustomerList();

customers.Customers.Add("Apple");
customers.Customers.Add("Microsoft");

c) The third option is to implement IEnumerable interface, but however, considering the requirement of your code, and fact that you are still learning C#, I would say it might be an overkill. It would be better to get a firm understanding of Collections and Classes/Properties first, before you actually go ahead with IEnumerable implementation

Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • So in my position would it just be best to make the List customers public. rather then try and learn about IEnumerable ? im guessing that making this list public is not best practice but at this stage would it matter ? would i get into any trouble by doing so. – Matt Leyland May 28 '19 at 16:52
  • Instead of making the member variable public, I would suggest make it a Property. It is perfectly fine to have public properties. – Anu Viswan May 28 '19 at 16:53