如何使用泛型where子句检查也具有泛型类型的类类型

时间:2019-05-14 17:22:03

标签: c# generics

我有一个由各种不同类继承的Entity类。在这个Entity类中,我有一个名为Identity的属性,该属性的类型基于TIdentity泛型类型。我正在制作另一个具有Entity通用类型的类,例如EntityCollection。我不知道如何为Entity类设置where子句。我需要该特定类的where子句,因为我需要访问EntityCollection类中的Identity属性。

这是Entity类。

public abstract class Entity<TIdentity> where TIdentity : Identity, new()
{
    protected Entity()
    {
        Identity = new TIdentity();
    }

    public TIdentity Identity { get; protected set; }
} 

这是Identity类:

public abstract class Identity
{
    protected Identity()
    {
        Id = Guid.NewGuid();
    }

    protected Identity(Guid id)
    {
        Id = id;
    }

    public Guid Id { get; }
}

这是一个继承Entity的类:

public class Example : Entity<ExampleId>
{
    public Example()
    {
    }

    //...Properties specific to this class. Not relevant to this question.
}

这是一个继承Identity的类:

public class ExampleId : Identity
{
    public Example()
    {
    }

    public Example(Guid id) : base(id)
    {
    }
}

第一次尝试:

public class EntityCollection<TEntity> : CustomCollection<TEntity> where TEntity : Entity
{
    public EntityCollection(IEnumerable<TEntity> collection) : base(collection)
    {
        RemovedItems = new List<TEntity>();
    }

    private EntityCollection(IEnumerable<TEntity> collection, IEnumerable<TEntity> removedItems) : base(collection)
    {
        RemovedItems = removedItems;
    }

    public EntityCollection<TEntity, TIdentity> New(IEnumerable<TEntity> newCollection)
    {
        var newCollectionList = newCollection.ToList();
        var newCollectionIds = newCollectionList.Select(item => item.Identity).ToList();
        var removedItems = new List<TEntity>();

        foreach (var item in Collection)
        {
            if (!newCollectionIds.Contains(item.Identity))
            {
                removedItems.Add(item);
            }
        }

        return new EntityCollection<TEntity, TIdentity>(newCollectionList, removedItems);
    }
}

这让我咆哮道:“使用通用类型'Entity'需要1个类型参数。”所以第一次尝试失败了。

第二次尝试:

public class EntityCollection<TEntity, TIdentity> : CustomCollection<TEntity> 
    where TIdentity : Identity, new() 
    where TEntity : Entity<TIdentity>
{
    public EntityCollection(IEnumerable<TEntity> collection) : base(collection)
    {
        RemovedItems = new List<TEntity>();
    }

    private EntityCollection(IEnumerable<TEntity> collection, IEnumerable<TEntity> removedItems) : base(collection)
    {
        RemovedItems = removedItems;
    }

    public EntityCollection<TEntity, TIdentity> New(IEnumerable<TEntity> newCollection)
    {
        var newCollectionList = newCollection.ToList();
        var newCollectionIds = newCollectionList.Select(item => item.Identity).ToList();
        var removedItems = new List<TEntity>();

        foreach (var item in Collection)
        {
            if (!newCollectionIds.Contains(item.Identity))
            {
                removedItems.Add(item);
            }
        }

        return new EntityCollection<TEntity, TIdentity>(newCollectionList, removedItems);
    }
}

这如我所愿。这里唯一的问题是我真的不想说TIdentity,因为实体已经在定义它了

目前,我已经使用了第二次尝试解决方案。但是,如果有任何人有更好的解决方案,那么一定要分享您的答案。如果我找到了更好的解决方案,我将更新这篇文章。

1 个答案:

答案 0 :(得分:0)

这是完全明智的,但遗憾的是,目前尚不支持。它称为更高种类的参数多态性Roslyn feature