【问题标题】:c# pass class inheritance from generic abstract class in generic paramc# 在泛型参数中从泛型抽象类传递类继承
【发布时间】:2017-10-03 13:52:14
【问题描述】:

我有这个树接口/类

BaseRepository.cs

abstract public class BaseRepository<Entity> : IRepository
    where Entity : BaseEntity, new()
{
    public virtual IList<Entity> FindAll()
    {
        ...
        return list;
    }
}

尝试使用泛型自动化获取、更新、插入 webapi 创建

BaseApiController

public class BaseEntityApiController<Repository> : ApiController
    where Repository : BaseRepository<BaseEntity>, new()
{
    Repository repository = new Repository();

    public IList<BaseEntity> Get()
    {
         return repository.FindAll();
    }

}

用户存储库

public class UserRepository : BaseRepository<User>
{  
}

我创建了一个从 BaseApiController 继承并传递 UserRepository 的新控制器:

用户控制器

public class UserController : BaseApiController<UserRepository>
{
}

我收到此错误:

Project.UserRepository cannot be used as type parameters 'Repository' in the generic type or method 'BaseApiController<Repository>'. There is no implicit reference conversion from Project.UserRepository to Project BaseRepository<Project.BaseEntity>.

如何将我的通用类型 UserRepository 传递给我的 BaseApiController 以自动创建所有控制器中使用的 Api?

【问题讨论】:

  • User 是否继承自 BaseEntity
  • @Flater 是用户从 BaseEntity 继承
  • 我会将访问修饰符放在抽象之前。 code 公共抽象类 BaseRepository : IRepository code

标签: c# generics inheritance abstract-class type-constraints


【解决方案1】:

将实体类型的泛型类型参数添加到您的 BaseEntityApiController 定义中:

public class BaseEntityApiController<TRepository, TEntity> : ApiController
    where TRepository : BaseRepository<TEntity>, new()
    where TEntity : BaseEntity, new()
{
    // ...
}

【讨论】:

  • 它有效,但我的目标是不定义两个泛型,因为存储库具有我需要在此继承中定义的 TEntity(TEntity 是我的 ): public class UserRepository : BaseRepository { }
  • 您可以让它以这种方式或您的方式工作并损坏。包含 TEntity 类型参数不是问题 - 通用类型约束将确保您不会为 repo/entity args 混合和匹配不同的实体类型。您还可以删除Repository 的泛型类型参数并使用TEntity 通过反射构造您的Repository 对象,但不会在编译时检查Repository&lt;T&gt; 实现是否具有无参数构造函数。
  • 是的,我尝试在 baseApi 通用声明中更改我的实体,但出现错误。我认为第一个解决方案是最好的。谢谢
【解决方案2】:

确保:

public class User: BaseEntity
{  
}

你可能也想要一个双泛型:

public class BaseEntityApiController<Repository, BaseEntity> : ApiController
    where Repository : BaseRepository<BaseEntity>, new()
{
    Repository repository = new Repository();

    public IList<BaseEntity> Get()
    {
         return repository.FindAll();
    }

}

这样您就不必投射如下内容:

UserController.Get().Cast<User>()

只是做:

public class UserController : BaseEntityApiController<UserRepository, User>{}
UserController.Get()

一次双重定义泛型与不断从 BaseEntity 转换为 User

【讨论】:

  • 我在 BaseEntityApiControlle 中收到一个错误:类型“BaseEntity”不能用作泛型类型或方法“BaseRepository”中的类型参数“Entity”。没有从“BaseEntity”到“Project.BaseEntity”的装箱转换或类型参数转换“BaseEntity”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法中的参数“Entity” 'BaseRepository'
  • 添加 moho 发布的代码我没有收到任何错误,但我的目标不是两次实体通用,因为存储库知道要使用的实体是什么。有什么改变不重复吗?
  • 是的,使用泛型 Co 或逆变
猜你喜欢
  • 2021-07-05
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
相关资源
最近更新 更多