使用继承时排除泛型类型

本文关键字:排除 泛型类型 继承 | 更新日期: 2023-09-27 17:49:19

我有这个GenericRepository类,我打算将其用作其他存储库的基类。我像这样构建我的泛型方法…

public class GenericRepository
{
    public void Insert<TEntity>(TEntity entity) where TEntity : class
    {
        var collection = GetCollection<TEntity>();
        collection.Save<TEntity>(entity);
    }
}

我的问题是……

是否有可能以一种方式继承GenericRepository,使您在调用每个方法时不必显式地包括泛型类型?例如,如果我有一个UserRepository : GenericRepository,我将能够写:

var repo = new UserRepository();
repo.Insert(user);
// Instead of
repo.Insert<User>(user);

使用继承时排除泛型类型

您不需要做任何事情。如果user确实是User类型,这只会起作用,因为编译器会推断出该类型。

但是你真的应该把你的类层次改成这样,也就是说,在类的层次上使用泛型参数:

public class GenericRepository<TEntity> where TEntity : class
{
    public void Insert(TEntity entity) 
    {
        var collection = GetCollection<TEntity>();
        collection.Save<TEntity>(entity);
    }
}
public class UserRepository : GenericRepositry<User>
{
    //...
}
背景:

当您扩展存储库时,您将看到为什么:

public class GenericRepository
{
    public void Insert<TEntity>(TEntity entity) where TEntity : class
    {
        var collection = GetCollection<TEntity>();
        collection.Save<TEntity>(entity);
    }
    public void Delete<TEntity>(TEntity entity) where TEntity : class
    {
         // ...
    }
}

这段代码是可能的,但没有任何意义,因为每个存储库实例应该只负责一种类型:

var genericRepository = new GenericRepository();
genericRepository.Insert(new User());
genericRepository.Delete(new Comment());
public class UserRepository : GenericRepository<User> {}

如果类型是非二义性的,c#已经允许省略泛型类型。但是,它不会提供编译时检查类型是否为User;为此,您需要将类型参数作为存储库的一部分,如下所示:

public class GenericRepository<TEntity> where TEntity : class
{
    public void Insert(TEntity entity)
    {
        var collection = GetCollection<TEntity>();
        collection.Save<TEntity>(entity);
    }
}
public sealed class UserRepository : GenericRepository<User> { ... }

不需要继承来获得这种效果。c#编译器有一个称为类型推断的特性,它允许它在许多情况下推断泛型方法参数的类型。例如,下面的代码可以很好地编译。

var repository = new GenericRepository();
User u = ...;
repository.Insert(u);

这里传递给Insert的类型是User,因此编译器可以很容易地推断出TEntity在这种情况下必须是User,并允许您省略该参数。