簡體   English   中英

從type參數的實例創建通用類型的實例

[英]Creating instance of a generic type from a instance of the type parameter

我有一個由通用存儲庫和一些針對幾種實體類型的特定實現組成的BL(我的DAL是Entity Framework 5模型)。 存儲庫幾乎使用System.Data.Entity.DbContext的Set()方法來實現所有功能。 我有一些用於獲取實體T的同級對象的表達式,這些表達式不適用於Set(Type entityType)的結果。

有一瞬間,我有一個非通用DbEntityEntry的實例。 該實體的類型為Object。 當我使用GetType()時,我得到適當的實體類型。 我知道要使用存儲庫中的函數來獲取相關實體。 有沒有一種方法可以從非泛型DbEntityEntry中做到這一點。

我試過了:

public Repository(T entity)
{
    \\ Construction here
}

但是我得到一個Repository<Object> ,對Set<Object>的調用未返回任何預期的結果。

我一直在尋找一種方法來做,但是空了。

泛型類型的構造函數是為其泛型類型參數生成的特定類的一部分。 例如, List<int>的構造函數與List<string>構造函數是不同的 換句話說,“查找”類型的代碼不能存在於泛型類中。

據我所知,這是您的兩個選擇:

  • 將對象轉換為其實際類型(類似於工廠的解決方案)
  • 使用反射創建泛型類實例

要使用反射創建實例,可以使用:

Type genericType = typeof(List<>);
Type genericArgument = typeof(int);
Type specificType = genericType.MakeGenericType(genericArgument);
object instance = Activator.CreateInstance(specificType); // this is a List<int>

讓我們看一下George Mauer在主題中發布的示例。 它要求.Net 4.0或更高版本。

dynamic DynamicCast(object entity, Type to)
{
    var openCast = this.GetType().GetMethod("Cast", BindingFlags.Static | BindingFlags.NonPublic);
    var closeCast = openCast.MakeGenericMethod(to);
    return closeCast.Invoke(entity, new[] { entity });
}
static T Cast<T>(object entity) where T : object
{
    return entity as T;
}

您可以使用對此稍加修改的變體來創建匹配的Repository實例:

public static dynamic CreateRepository(object entiry, Type targetType)
{
    Type BaseType = typeof(Repository<>);   
    Type ConcreteType = BaseType.MakeGenericType(targetType);
    var Instance = Activator.CreateInstance(ConcreteType, entiry);

    return DynamicCast(Instance, ConcreteType);
}

如果可以將泛型類型約束為具有無參數構造函數,則可以很好地解決此問題

public Repository(T entity) where T : new()
{
    T foo = new T(); //that's it
}

你可以做:

T entity = default(T);

這適用於T的值類型以及結構和類。 但是,在T是一個類的情況下,它確實需要無參數的構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM