【问题标题】:Unable to infer generic type from a collection无法从集合中推断泛型类型
【发布时间】:2012-01-19 02:21:04
【问题描述】:

为什么不能这样做:

public static void Init<TEntity>(params TEntity[] repositories) where TEntity : Entity
{
    foreach (TEntity item in repositories)
    {
       Repository<item> rep = new Repository<item>();
    }
}

以上代码无法编译:无法解析符号项

但这是可行的:

public static void Init<TEntity>(TEntity entity) where TEntity : Entity
{
    Repository<TEntity> rep = new Repository<TEntity>();
}

编辑

我正在编辑 OP 以更全面地了解问题。我们遇到了由多个存储库生成的实体框架 Db Context 的一些问题。目前我们访问的存储库如下:

Repository<Product> rep = new Repository<Product>()
Repository<Account> rep = new Repository<Account>()

由于产品和帐户之间存在关系,EF 会抱怨对象附加到不同的上下文。因此,我们试图通过将存储库访问整合到工作单元模式中来解决这个问题:

这是我想要实现的一个示例:

public class UnitOfWork
{
    protected List<Entity> Repositories = new List<Entity>();
    private readonly DbContext _context;
    protected UnitOfWork()
    {
       _context = new SqlDbContext();
    }

    public static UnitOfWork Init<TEntity>(params TEntity[] repositories) where TEntity : Entity
    {
            UnitOfWork uow = new UnitOfWork();
        foreach (TEntity item in repositories)
        {
            Repository<item> rep = new Repository<item>();
            uow.Repositories.Add(rep);
        }
            return uow;
    }

    public IRepository<T> GetRepository<T>() where T : Entity
    {
        return Repositories.OfType<T>().Single();
    }   
}

所以我们可以像这样访问我们的存储库:

GetRepository<Product>().GetById(1);
GetRepository<Account>().GetById(123434);

【问题讨论】:

  • 我不确定您为什么需要这样做。如果您知道该项目是 TEntity 类型,并且您正在尝试从项目的类型创建一个通用存储库,为什么不直接做 Repository
  • 您的第一个代码显然是错误的,泛型是基于 T 的编译时功能,其中 T 是一个实际的类型参数,如 stringFoo。您正在尝试使 T 成为变量,但这是行不通的。但是您真正需要做什么?
  • 我们在管理跨多个存储库的实体框架上下文时遇到问题,因此尝试将所有存储库放入工作单元模式,以便我们可以使用 DbContext 的单个实例。
  • 既然你已经传入了类型,为什么不能在类外创建存储库并传入列表?

标签: c# generics type-inference


【解决方案1】:

item 是一个类型的实例,但您需要一个类型参数来创建泛型Repository&lt;T&gt; 类的实例。

【讨论】:

    【解决方案2】:

    不确定是什么让您尝试第一种情况 (Repository&lt;item&gt; rep = new Repository&lt;item&gt;();)。在这里,“item”是一个实例而不是一个类型。如果您需要通用物品,您的第二种情况会做得最好。

    请详细说明您的“问题”。

    编辑: 如果这个问题是出于好奇,那么你可以看看 'MakeGenericType) 方法,下面的代码解释了用法。

           Type generic = typeof(Repository<>);
    
           Type[] typeArgs = { item.GetType() };
    
           Type constructed = generic.MakeGenericType(typeArgs);
    // This will create Repository<item> type.
    

    【讨论】:

    • 用一些背景信息编辑我的 OP
    【解决方案3】:
        public static UnitOfWork Init<T1>()
        {
            UnitOfWork uow = new UnitOfWork();
            uow.Add(new Repository<T1>());
            return uow;
        }
    
        public static UnitOfWork Init<T1,T2>()
        {
            UnitOfWork uow = Init<T1>();
            uow.Add(new Repository<T2>());
            return uow;
        }
    
        public static UnitOfWork Init<T1, T2, T3>()
        {
            UnitOfWork uow = Init<T1,T2>();
            uow.Add(new Repository<T3>());
            return uow;
        }
    
        // ...
    

    【讨论】:

      【解决方案4】:

      这是不正确的语法。 Item 是 TEntity 类型的实例。您不使用具有泛型定义的实例变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多