Reputation: 399
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
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
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
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