从变量实例化泛型类型

Instantiate generic type from variable

我想实例化一个新对象,其中类型和通用类型定义为变量。最终结果可能类似于此处手动创建的 newListOfObjects:

var newListOfObjects = new List<TabViewModel>();

其中 TabViewModel 是以下对象:

public class TabViewModel
{
    public string Title { get; set; }
    public int TabOrder { get; set; }
}

当尝试仅使用变量实例化新对象时出现问题。我们有一个泛型类型变量 genericType,它是一个接口和一个类型参数列表 listOfTypeArgs。在上面的示例中,泛型类型是 IList,参数是 TabViewModel。然后它看起来像下面这样(注意,一些代码是 psudo 以便于理解):

Type genericType = IList'1;
Type[] listOfTypeArgs = TabViewModel;
var newObject = Activator.CreateInstance(genericType.MakeGenericType(listOfTypeArgs));

很明显,我得到了错误 'System.MissingMethodException',并指出我无法从接口实例化变量。

如何将接口转换为它的代表,以便我可以 实例化新对象?

注意:我无法更改类型 genericType = IList'1;也不 类型[] listOfTypeArgs = TabViewModel;

您需要像这样使用 List<> 类型:

var genericType = typeof(List<>);
var boundType = genericType.MakeGenericType(typeof(TabViewModel));
var instance = Activator.CreateInstance(boundType);

错误是自我描述的,您需要具体类型才能创建实例。您需要使用 IList:

的实现,而不是 IList (它没有实现,只是一个合同)
Type genericType = typeof(List<>);
Type[] listOfTypeArgs = new[] { typeof(TabViewModel) };
var newObject = Activator.CreateInstance(genericType.MakeGenericType(listOfTypeArgs));

编辑:

如果您没有具体类型,则需要使用容器或反映当前程序集来获取它。下面是一些 hack,您需要调整您认为对您的案例有用的方式。

Type genericType = typeof(List<>);
Type concreteType = AppDomain.CurrentDomain.GetAssemblies()
                            .SelectMany(s => s.GetTypes())
                            .Where(p => genericType.IsAssignableFrom(p)).FirstOrDefault();

Type[] listOfTypeArgs = new[] { typeof(TabViewModel) };
var newObject = Activator.CreateInstance(concreteType.MakeGenericType(listOfTypeArgs));