简体   繁体   English

给定另一个对象的类型,通过反射来构造泛型

[英]Construct a generic type through reflection given the type of another object

I'm passing a type to a method and creating an object based on that type. 我将类型传递给方法,并基于该类型创建对象。 Assume argType is a Type and passed to the method as a parameter. 假设argType是一个Type并作为参数传递给该方法。

var assembly = AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "MyAssembly");
var newType = assembly.GetTypes().SingleOrDefault(x => x.FullName == argType.FullName + "Suffix");
var newObject = Activator.CreateInstance(newType);

This works fine for most objects, but if I pass a type with a generic sub type (eg MyClass<MyType> ), it fails [Assume the goal is to set newObject to a MyClassSuffix<MyType> ]. 这对于大多数对象都可以正常工作,但是如果我传递带有泛型子类型的类型(例如MyClass<MyType> ),则会失败[假设目标是将newObject设置为MyClassSuffix<MyType> ]。

How could the code above be improved so that generic types (ending with "Suffix") can also be created? 如何改进上面的代码,以便也可以创建泛型(以“后缀”结尾)? I looked at the FullName property for such types which contain substrings like '1[[ . 我查看了包含诸如'1[[等子字符串]之类'1[[此类的FullName属性。 I'd rather not do regex parsing to append "Suffix" before these characters begin. 在这些字符开始之前,我宁愿不进行正则表达式解析以附加“后缀”。 I'm thinking there is a better way. 我在想有一种更好的方法。

You can use MakeGenericType method if you have instance of both types ie the generic class and the generic type parameter : 如果您同时具有两种类型的实例,即泛型类和泛型类型参数,则可以使用MakeGenericType方法:

// assuming you have a generic class named Class<> 
// taking one generic type parameter
Type generic = typeof(MyClassSuffix<>);
Type typeParameter = typeof(MyClass);
Type genericInstance = generic.MakeGenericType(typeParameter);

and then: 接着:

object o = Activator.CreateInstance(genericInstance);

In your case you have generic as newType and you would need to figure out which type you need to pass as type parameter and it should work. 在您的情况下,您将generic用作newType ,则需要确定需要将哪种类型作为类型参数传递,并且该类型应该起作用。

Read the following MSDN docs for detailed instructions on this topic: 阅读以下MSDN文档,以获取有关此主题的详细说明:

https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-examine-and-instantiate-generic-types-with-reflection https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-examine-and-instantiate-generic-types-with-reflection

UDPATE: UDPATE:

You can get generic type parameters too following way 您也可以通过以下方式获取通用类型参数

    var newType = assembly.GetTypes().SingleOrDefault(x => x.FullName == argType.FullName + "Suffix");
     if(newType.IsGenericType)
     {
        // Get the generic type parameters or type arguments.
        Type[] typeParameters = t.GetGenericArguments();

        // Construct the type Dictionary<String, Example>.
        Type constructed = newType.MakeGenericType(typeParameters);
     }

If you are having a closed type then you can instantiate it same way like a normal class. 如果您使用的是封闭类型,则可以像普通类一样实例化它。 See the following example: 请参见以下示例:

public class GenericClass<Int>
{

}

Now we can generate an instance of it like: 现在我们可以生成它的一个实例,例如:

 Type t = typeof(GenericClass<int>);
 object o = Activator.CreateInstance(y);
 Console.WriteLine(o);

DEMO Fiddle 演示小提琴

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

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