c# - 从变量实例化泛型类型

标签 c# variables object generics instantiation

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

var newListOfObjects = new List<TabViewModel>();

其中 TabViewModel 是以下对象:

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

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

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

很明显,我收到错误“System.MissingMethodException”,并指出我无法从接口(interface)实例化变量。

如何将接口(interface)转换为其代表,以便我可以 实例化新对象?

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

最佳答案

该错误是自描述性的,您需要具体类型来创建实例。您需要使用 IList 的实现,而不是 IList(它没有实现,只是一个合约):

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

编辑:

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

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));

关于c# - 从变量实例化泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39890197/

相关文章:

java - 创建新变量与重用旧变量哪个更快?

java - 使用 Java comparable 按名称对对象进行排序

c# - 异常抛出

C# 可以将 string[] 与其他 4 个 string[] 进行比较吗?

c# - 如何在 C# 中通过所有者控制类可见性

events - VBScript 中的 COM 事件处理程序

php - PHP 中的 “Unexpected T_OBJECT_OPERATOR” 错误

c# - 将 RTF 格式转换为 HTML 标签

php - 有没有更简洁的方法来设置默认值?

jquery - 使用 jQ 和 Ajax 将一个简单的变量传递给 Ruby