Reputation: 1341
I wanted to know the way to LINQ a generic collection.
My Customer class is as
class Customer
{
public string Name { get; set; }
public string id { get; set; }
}
My collection class is
class genericCollection<T> : CollectionBase
{
public void add(T GenericObject)
{
this.List.Add(GenericObject);
}
}
Then I add some data to customer collection
genericCollection<Customer> customers = new genericCollection<Customer>();
customers.add(new Customer {id= "1",Name="Andy"});
customers.add(new Customer { id = "2", Name = "MArk" });
customers.add(new Customer { id = "3", Name = "Jason" });
customers.add(new Customer { id = "4", Name = "Alex" });
Now i can iterate through customers object using a foreach loop but how can i linq it.
I want to use something like
var query = from c in customers
select c;
But I am not able to successfully cast it.
Regards, Sab
Upvotes: 4
Views: 10574
Reputation: 33
Now, there is a library which provides strongly-typed, queryable collections in typescript.
These collections are:
The library is called ts-generic-collections-linq.
Source code on GitHub:
https://github.com/VeritasSoftware/ts-generic-collections
NPM:
https://www.npmjs.com/package/ts-generic-collections-linq
With this library, you can create collections (like List<T>
) and query them as shown below.
let owners = new List<Owner>();
let owner = new Owner();
owner.id = 1;
owner.name = "John Doe";
owners.add(owner);
owner = new Owner();
owner.id = 2;
owner.name = "Jane Doe";
owners.add(owner);
let pets = new List<Pet>();
let pet = new Pet();
pet.ownerId = 2;
pet.name = "Sam";
pet.sex = Sex.M;
pets.add(pet);
pet = new Pet();
pet.ownerId = 1;
pet.name = "Jenny";
pet.sex = Sex.F;
pets.add(pet);
//query to get owners by the sex/gender of their pets
let ownersByPetSex = owners.join(pets, owner => owner.id, pet => pet.ownerId, (x, y) => new OwnerPet(x,y))
.groupBy(x => [x.pet.sex])
.select(x => new OwnersByPetSex(x.groups[0], x.list.select(x => x.owner)));
expect(ownersByPetSex.toArray().length === 2).toBeTruthy();
expect(ownersByPetSex.toArray()[0].sex == Sex.F).toBeTruthy();
expect(ownersByPetSex.toArray()[0].owners.length === 1).toBeTruthy();
expect(ownersByPetSex.toArray()[0].owners.toArray()[0].name == "John Doe").toBeTruthy();
expect(ownersByPetSex.toArray()[1].sex == Sex.M).toBeTruthy();
expect(ownersByPetSex.toArray()[1].owners.length == 1).toBeTruthy();
expect(ownersByPetSex.toArray()[1].owners.toArray()[0].name == "Jane Doe").toBeTruthy();
Upvotes: 0
Reputation: 21
Working with:
public void add(T GenericObject)
{
this.List.Add(GenericObject);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.List.OfType<T>().GetEnumerator();
}
Upvotes: 0
Reputation: 43036
Some answers suggest using customers.OfType<Customer>
; this tests the type of every object in the collection before converting it. You know that each object is of that type, so you don't need the runtime type check. For that reason, you should use customers.Cast<Customer>
instead.
Having said that, I agree that it would be better not to use CollectionBase
in the first place; it would be better to use a generic collection type; if you prefer to define your own collection type, then you should derive from (or delegate to) a generic collection.
Upvotes: 3
Reputation: 19692
You need to implement the IEnumerable<T>
interface:
public class genericCollection<T>: CollectionBase, IEnumerable<T>{}
Upvotes: 1
Reputation: 16130
You can specify type in LINQ query:
var query = from Customer c in customers select c;
or implement IEnumerable<T>
for eg:
class genericCollection<T> : CollectionBase, IEnumerable<T>
{
public void add(T GenericObject)
{
this.List.Add(GenericObject);
}
public IEnumerator<T> GetEnumerator()
{
return this.List.Cast<T>().GetEnumerator();
}
}
Upvotes: 1
Reputation: 3972
try to change your query to the following (assuming that your CollectionBase
implements IEnumerable
):
var query = from c in customers.OfType<Customer>() select c;
or let your genericCollection<T>
implement IEnumerable<T>
Upvotes: 5
Reputation: 45071
The problem is that you derive from CollectionBase
. You should also implement ICollection<T>
and no cast is needed anymore.
Upvotes: 1
Reputation: 34349
The LINQ standard query operators are extension methods defined for IEnumerable
and IEnumerable<T>
. You could try:
class genericCollection<T> : Collection<T>
or use another collection type such as List<T>
Upvotes: 2