2012-01-19 53 views
1

爲什麼不可能做到這一點:無法從集合推斷泛型類型

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

我不知道爲什麼你需要做到這一點。如果您知道該項目的類型爲TEntity,並且您嘗試從項目類型創建通用Repository,那麼爲什麼不直接執行Repository ? –

+0

你的第一個代碼顯然是錯誤的,泛型是基於T的編譯時功能,其中T是一個實際的類型參數,比如'string'或'Foo'。你試圖讓T變成一個變量,這是不行的。但是你真的需要做什麼? –

+0

我們遇到了跨多個存儲庫管理實體框架上下文的問題,因此試圖將所有存儲庫放入工作單元模式,以便我們可以使用DbContext的單個實例。 – Fixer

回答

4

item是一個實例的一個類型,但是您需要一個類型參數來創建一個通用的Repository<T>類的實例。

0

這是不正確的語法。 Item是一個TEntity類型的實例。您不使用具有通用定義的實例變量。

2

不確定是什麼讓您嘗試第一種情況 (Repository<item> rep = new Repository<item>();)。在這裏,'item'是一個實例,而不是一個類型。如果你需要一個genertic項目你的第二個案件最好。

請詳細說明您的問題。

編輯: 如果這個問題是出於好奇,那麼你可以看看'MakeGenericType)方法,下面的代碼解釋了用法。

 Type generic = typeof(Repository<>); 

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

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

編輯我的OP與一些背景信息 – Fixer

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

    // ...