![](/img/trans.png)
[英]Create list of runtime-known type from object list and call generic method
[英]Create list of generic object at runtime
我有一些在運行時已知的類型的對象,我從數據庫中讀取和反序列化此對象。 有用。 現在我想將它添加到一些列表中:
private static List<T> generateList<T>()
{
List<T> lst = new List<T>();
return lst;
}
private void readObjects(System.Type objType)
{
var methodInfo = typeof(My.Serializator).GetMethod("DeserializeDb");
var genericMethod = methodInfo.MakeGenericMethod(objType1);
List<curType> currentList= generateList<curType>();
// ...read stream from database and convert it to object
while (_rs.Read())
{
var _objItem = genericMethod.Invoke(null, new[] { _streamedData });
currentList.Add(_objItem);
}
}
它不會起作用。 錯誤是:
curType是一個變量,但是像類型一樣使用。
如果我將列表更改為:
List<object> currentList = new List<object>();
它會工作。 但我能用泛型(T)代替對象類型嗎?
您可以通過Activator
輕松創建所需的列表類型,然后轉換為IList
並使用它:
private IList readObjects(System.Type objType)
{
var listType = typeof(List<>).MakeGenericType(curType);
var list = (IList)Activator.CreateInstance(listType);
// ...
while (_rs.Read())
{
// ...
list.Add(_objItem);
}
}
list
將是List<YorActualType>
實例。
更新
當您使用泛型參數聲明方法時,它假定您在編譯期間提供類型信息。 否則你需要使用反射。
由於您在運行時提供類型信息( curType
可以包含任何類型信息),編譯器不知道將使用什么樣的類型,並且您不能聲明您的方法返回具體的東西。 只允許抽象。
讓我用稍微瘋狂但示范性的例子來展示它:
var types = new [] { typeof(int), typeof(string) };
var rand = new Random();
var list = readObjects(types[rand.Next(0,2)];
直到最后一刻,即使你不知道究竟會創建什么類型的列表。 編譯器也不知道。 如果您沒有向他提供類型,編譯器將永遠不知道應該使用什么類型。 當你使用Type
,它只告訴編譯器一些類型為Type
常規參數將在運行時傳遞給方法。 在編譯期間沒有數據可以推斷出類型。 該數據只能通過泛型類型參數傳遞。
因此,有幾種方法可以遵循:
在編譯時提供所需的確切類型
private List<T> readObjects<T>() { var objType = typeof(T); var list = new List<T>(); // rest of code.... }
使用反射和基本類型
private IList readObjects(Type objType) { // rest of code with Activator and so on }
以后的使用取決於您的需求。 如果您知道要使用的類型,只需轉換:
var list = (IList<MyType>)readObjects(typeof(myType));
但我想在這種情況下更好地使用方式#1與泛型參數。
否則你將使用反射。 或者一些基類,接口等。 這取決於你要解決的具體任務。
PS您可以在MSDN上閱讀有關泛型類型的更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.