简体   繁体   English

从变量实例化泛型类型

[英]Instantiate generic type from variable

I would like to instantiate a new object where the type and generic type are defined as variables. 我想实例化一个新对象,其中类型和泛型类型被定义为变量。 The final result could look like the newListOfObjects created manually here: 最终结果可能类似于在此手动创建的newListOfObject:

var newListOfObjects = new List<TabViewModel>();

Where TabViewModel is the following object: TabViewModel是以下对象:

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

The problem comes when trying to instantiate the new object using only variables . 尝试仅使用变量实例化新对象时出现问题 We have one generic type variable, genericType, which is an interface and one list of type arguments, listOfTypeArgs. 我们有一个泛型类型变量genericType,它是一个接口和一个类型参数列表listOfTypeArgs。 In the example above the generic type would be IList and the arguments would be TabViewModel. 在上面的示例中,泛型类型将是IList,参数将是TabViewModel。 It would then look like following ( note, some code is psudo for easier understanding ): 然后它看起来像下面( 注意,一些代码是psudo以便于理解 ):

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

It is then obvious that I get the error 'System.MissingMethodException' with the note that I can not instantiate a variable from an interface. 很明显,我得到错误'System.MissingMethodException',注意我无法从接口实例化变量。

How can I convert the interface to its represenative so that I can instantiate the new object? 如何将接口转换为其代表,以便我可以实例化新对象?

NOTE: I can not change Type genericType = IList'1; 注意:我无法更改Type genericType = IList'1; nor Type[] listOfTypeArgs = TabViewModel; 也不是Type [] listOfTypeArgs = TabViewModel;

You need to use the List<> type like so: 您需要使用List<>类型,如下所示:

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

The error is self descriptive, you need concrete types to create an instance. 该错误是自描述的,您需要具体类型来创建实例。 Instead of IList (Which has no implementation and is just a contract), you need to use an implementation of IList : 而不是IList (没有实现,只是一个契约),你需要使用IList的实现:

Type genericType = typeof(List<>);
Type[] listOfTypeArgs = new[] { typeof(TabViewModel) };
var newObject = Activator.CreateInstance(genericType.MakeGenericType(listOfTypeArgs));

Edit: 编辑:

If you don't have a concrete type, you need to get it either using a container or reflecting the current assemblies. 如果您没有具体类型,则需要使用容器或反映当前程序集。 Below is a bit of a hack that you need to tweak the way you find useful for your case. 下面是一些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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM