Шыназ Алиш
Шыназ Алиш

Reputation: 399

How to use LINQ in my created class

Here i created MyList class. And i want to use LINQ with my class. Below my class:

class ListOfItems<T>: CollectionBase
    {
        List<T> list = new List<T>();
        public void Add(T car)
        {
            list.Add(car);
        }

        public void Add(T car, int index)
        {
            list.Insert(index, car);
        }
        public void Remove(int index)
        {
            list.RemoveAt(index);
        }

        public T getCar(int index)
        {
            return (T)list[index];
        }

        public int Count()
        {
            return list.Count;
        }

        public IEnumerable<T> getItems()
        {
            return list;
        }
    }

Also i created class Car to collect them in my list. Below my class Car:

class Car
    {
        public string Model { get; set; }
        public int Age { get; set; }
        public double Volume { get; set; }

        public Car(string model, int age, double volume)
        {
            Model = model;
            Age = age;
            Volume = volume;
        }

        public override string ToString()
        {
            return "Model: " + Model + " Age: " + Age + " Volume: " + Volume; 
        }
    }

After i created some instanse of class Car:

Car bmw = new Car("E34", 20, 2.5);
            Car audi = new Car("C5", 18, 2.8);
            Car toyota = new Car("camry", 20, 2.2);

            ListOfItems<Car> cars = new ListOfItems<Car>();
            cars.Add(bmw);
            cars.Add(audi);
            cars.Add(toyota);

And I want to use LINQ here like this:

Console.WriteLine((cars.Where<Car>(p => p.Volume >= 2.5)).ToString())

I understand that i have not implement interface GetEnumerator(). So i don't understand properly. I ask my friend(google) about it, but he says about LINQ IN SQL... So I need explaining, and advice in solving this problem. Or link to the source. Thank you.

Upvotes: 0

Views: 182

Answers (3)

Nameless One
Nameless One

Reputation: 1646

I would change the class definition to:

class ListOfItems<T> : CollectionBase, IEnumerable<T> 
{
    public void Add(T car)
    {
        InnerList.Add(car);
    }

    public void Add(T car, int index)
    {
        InnerList.Insert(index, car);
    }
    public void Remove(int index)
    {
        InnerList.RemoveAt(index);
    }

    public T GetCar(int index)
    {
        return (T)InnerList[index];
    }

    public int Count()
    {
        return InnerList.Count;
    }

    public IEnumerable<T> GetItems()
    {
        return InnerList.Cast<T>();
    }

    public IEnumerator<T> GetEnumerator()
    {
        return this.GetItems().GetEnumerator();
    }
}

This way you use the ArrayList given to you by CollectionBase, and you can use LINQ like you requested:

foreach(var car in cars.Where(c => c.Volume >= 2.5))
{
    Console.WriteLine(car.ToString());
}

EDIT:

If you dislike the foreach loop, then you can go overboard by doing:

    Console.WriteLine(cars.Where(c => c.Volume >= 2.5)
                      .Aggregate(new StringBuilder(),
                                (builder, c) => builder.AppendFormat("{0}{1}", c, Environment.NewLine)).ToString());

Honestly though, I don't see why you want to use CollectionBase, I would throw it away and just wrap a List<T> like you did, and implement IEnumerable<T> like I showed.

Upvotes: 0

Coder1409
Coder1409

Reputation: 498

I advice you add another Class Named Cars that implements IEnumerable

 class Cars : IEnumerable<Car>
{
    Car[] cars;
    public Cars(Car[] cars)
    {
        this.cars = cars;
    }

    public IEnumerator<Car> GetEnumerator()
    {
        for (int index = 0; index < cars.Length; index++)
            yield return cars[index];
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Then you can create an array of Car pass it as an argument to Cars as follow

Var C=new Cars(carArray);

And you can call the LINQ as follow

Console.Writeline(C.SingleOrDefault(c=>c.Model=="Audi").ToString());

Update

Here is the generic version of the class

 class GenericClass<T> : IEnumerable<T>
{
    T[] elements;
    public GenericClass(T[] elements)
    {
        this.elements = elements;
    }

    public IEnumerator<T> GetEnumerator()
    {
        for (int index = 0; index < cars.Length; index++)
            yield return elements[index];
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Upvotes: 1

sll
sll

Reputation: 62544

To achieve what you need you have to implement IEnumerable<T> as well as 'CollectionBase' that should help, CollectionBase provides IEnumerable only

See alos LINQ and Generic Types

Upvotes: 1

Related Questions