[英]Dynamic type with lists in c#
我有一點問題。
我想這樣做:
Type[] classes = new Type[]{ Class1, Class2 };
foreach(Type t in classes){
List<t> list = new List<t>();
}
有辦法做到這一點嗎?
您不能在運行時轉換為泛型類型,因為泛型中的類型需要在編譯時解析。
您可以使用反射以動態方式創建泛型類型,但除非您對強制轉換進行硬編碼,否則您獲得的所有內容都是對象。
我不能真正說出你想要的是什么,我不得不同意這是一個XY問題 。 我傾向於做出這樣一種冒昧的陳述:這是一個設計問題,它試圖解決,而不是直接解決設計問題,或者詢問你想要直接實現的問題。
您可以使用以下代碼創建類型,然后dynamic
類型可用於在不知道/關心它是列表或T
是什么的情況下對List<T>
的各種成員進行類型化 :
using System;
using System.Collections.Generic;
namespace ConsoleApplication61
{
class Program
{
static void Main(string[] args)
{
dynamic o = CreateGeneric(typeof(List<>), typeof(int));
o.Add(1);
Console.WriteLine(o[0]);
Console.Read();
}
public static object CreateGeneric(Type generic, Type innerType, params object[] args)
{
System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
return Activator.CreateInstance(specificType, args);
}
}
}
上面的示例duck類型是Add
方法和Indexer。 DLR在運行時執行類型處理和鴨子類型 - 例如,知道1
是int
。
只是為了澄清,我可能不會在生產中使用這樣的代碼(除非你的要求非常具體需要這個),並且任何類型不匹配的問題都會在運行時發生; 因此您需要非常准確地鍵入(有限的IntelliSense)或具有良好的錯誤處理。
這假定.NET 4具有新的CLR。 正如@MartinLiversage也指出的那樣,這個特定的示例假設您以強類型的方式使用列表。 在我的例子中,我將一個int
傳遞給dynamic
隱藏的List<int>
。
自從它發布以來,我們一直在使用.NET 4。 我們有一個大型應用程序,具有更大的代碼庫。 dynamic
在應用程序中不使用一次,在測試代碼庫中只使用幾次。 這並不是說“不要使用它”,而是說“大多數時候,你不需要它”。
你可以這樣做:
foreach(Type t in classes)
{
var listType = typeof(List<>).MakeGenericType(t);
var instance = Activator.CreateInstance(listType);
}
這是一個我發現應該適用於ya的漂亮方法: CodeRef
public static object CreateGeneric(Type generic, Type innerType, params object[] args)
{
System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
return Activator.CreateInstance(specificType, args);
}
並像這樣使用它:
var o = CreateGeneric(typeof(List<>), t);
不幸的是,要添加項目,您必須這樣做(其中item是您要添加的項目)。
MethodInfo addMethod = o.GetType().GetMethod("Add");
addMethod.Invoke(o, new object[] { item.ToType(t) });
或者使用另一個答案中提到的Generic
類型。
你可以試試這個:
Type[] classes = new Type[] { typeof(A), typeof(B) };
foreach (Type t in classes)
{
Type genericType = typeof(List<>).MakeGenericType(t);
var list = Activator.CreateInstance(genericType);
}
如果你想在一個列表中保留對象,那么它們可能有一些共同之處。
在這種情況下,我認為,就像評論中提到的LB一樣,你在這里提出了一個錯誤的問題。
可能這是你的設計問題。 考慮一下這些類型,看看它們有什么共同點,並考慮從一種基本類型派生,或者兩者都實現相同的接口。 在這種情況下,您將能夠實例化基本類型/接口的對象列表並使用它們。
只是為了給你一個良好的開端:
abstract class Vehicle {
public int NumberOfWheels { get; set; }
}
class Car : Vehicle
{
public Car()
{
NumberOfWheels = 4;
}
}
class Bicycle : Vehicle
{
public Bicycle()
{
NumberOfWheels = 2;
}
}
static void Main(string[] args)
{
var v1 = new Car();
var v2 = new Bicycle();
var list = new List<Vehicle>();
list.Add(v1);
list.Add(v2);
foreach (var v in list)
{
Console.WriteLine(v.NumberOfWheels);
}
Console.ReadKey();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.