如何使用LINQ查询泛型集合

本文关键字:泛型 集合 查询 LINQ 何使用 | 更新日期: 2023-09-27 18:19:26

我想知道LINQ通用集合的方法。

我的客户类别为

 class Customer
    {
        public string Name { get; set; }
        public string id { get; set; }
    }

我的收藏类是

class genericCollection<T> : CollectionBase
{
    public void add(T GenericObject)
    {
        this.List.Add(GenericObject);
    }
}

然后我添加一些数据到客户收集

  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" });

现在,我可以使用foreach循环遍历customers对象,但如何对其进行linq

我想用之类的东西

var query =  from c in customers
             select c;

但我没能成功铸造它。

谨致问候,Sab

如何使用LINQ查询泛型集合

尝试将查询更改为以下内容(假设CollectionBase实现IEnumerable):

var query = from c in customers.OfType<Customer>() select c;

或者让您的genericCollection<T>实现IEnumerable<T>

有些答案建议使用customers.OfType<Customer>;这将在转换集合之前测试集合中每个对象的类型。您知道每个对象都是该类型的,因此不需要运行时类型检查。因此,您应该使用customers.Cast<Customer>

话虽如此,我同意一开始最好不要使用CollectionBase;最好使用通用集合类型;如果您喜欢定义自己的集合类型,那么您应该从泛型集合派生(或委托给)泛型集合。

LINQ标准查询运算符是为IEnumerableIEnumerable<T>定义的扩展方法。你可以试试:
class genericCollection<T> : Collection<T>

或者使用另一种收集类型,如List<T>

问题是您从CollectionBase派生。您还应该实现ICollection<T>,并且不再需要强制转换。

您可以在LINQ查询中指定类型:

var query = from Customer c in customers select c;

或实现IEnumerable<T>,例如:

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();
    }
}

您需要实现IEnumerable<T>接口:

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

使用选择

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

使用:

    public void add(T GenericObject)
    {
        this.List.Add(GenericObject);
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return this.List.OfType<T>().GetEnumerator();
    }

现在,有一个库在typescript中提供强类型、可查询的集合。

这些集合是:

  • 列表
  • 词典

该库被称为ts泛型集合linq

GitHub上的源代码:

https://github.com/VeritasSoftware/ts-generic-collections

NPM:

https://www.npmjs.com/package/ts-generic-collections-linq

使用此库,您可以创建集合(如List<T>)并查询它们,如下所示。

    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();