无法从集合中推断泛型类型

时间:2012-01-19 02:21:05

标签: c# generics type-inference

为什么不可能这样做:

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);

4 个答案:

答案 0 :(得分:4)

item是类型的实例,但您需要一个类型参数来创建通用Repository<T>类的实例。

答案 1 :(得分:2)

不确定是什么让你尝试第一种情况 (Repository<item> rep = new Repository<item>();)。这里,'item'是一个实例,而不是一个类型。如果你需要一个基因项目,你的第二个案例最好。

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

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

       Type generic = typeof(Repository<>);

       Type[] typeArgs = { item.GetType() };

       Type constructed = generic.MakeGenericType(typeArgs);
// This will create Repository<item> type.

答案 2 :(得分:1)

    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;
    }

    // ...

答案 3 :(得分:0)

这是不正确的语法。 Item是TEntity类型的实例。您不要将实例变量与通用定义一起使用。