user1131926
user1131926

Reputation: 1341

how to use LINQ to query a generic collection

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

Answers (9)

Norman
Norman

Reputation: 33

Now, there is a library which provides strongly-typed, queryable collections in typescript.

These collections are:

  • List
  • Dictionary

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

odinspain
odinspain

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

softwarevamp
softwarevamp

Reputation: 857

Use Select:

customers.Select(x => {...})

Upvotes: 0

phoog
phoog

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

ilivewithian
ilivewithian

Reputation: 19692

You need to implement the IEnumerable<T> interface:

public class genericCollection<T>: CollectionBase, IEnumerable<T>{}

Upvotes: 1

Krzysztof
Krzysztof

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

Nuffin
Nuffin

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

Oliver
Oliver

Reputation: 45071

The problem is that you derive from CollectionBase. You should also implement ICollection<T> and no cast is needed anymore.

Upvotes: 1

devdigital
devdigital

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

Related Questions