使用继承时排除泛型类型

时间:2011-04-05 15:41:46

标签: c# c#-4.0

我有这个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);

4 个答案:

答案 0 :(得分:1)

你不需要做任何事情。如果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());

答案 1 :(得分:1)

public class UserRepository : GenericRepository<User> {}

答案 2 :(得分:1)

如果类型不明确,C#将允许您省略泛型类型。但是,它不会提供编译时检查,该类型是用户;为此,您需要将存储库的类型参数部分设置为:

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> { ... }

答案 3 :(得分:0)

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

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

此处传递给Insert的类型为User,因此编译器可以在此方案中轻松推断出TEntity必须为User,并允许您省略参数