代码之家  ›  专栏  ›  技术社区  ›  user246392

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

  •  1
  • user246392  · 技术社区  · 7 年前

    我将一个类型传递给一个方法,并基于该类型创建一个对象。假定 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);
    

    这适用于大多数对象,但如果我传递了一个带有泛型子类型的类型(例如。 MyClass<MyType> ),它失败了[假设目标是 newObject 到 MyClassSuffix<MyType> ].

    如何改进上述代码,以便也可以创建泛型类型(以“后缀”结尾)?我看了看 FullName 属性,该类型包含子字符串,如 '1[[ .我不希望在这些字符开始之前进行正则表达式解析以附加“后缀”。我在想有更好的办法。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Ehsan Sajjad    7 年前

    你可以用 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);
    

    然后:

    object o = Activator.CreateInstance(genericInstance);
    

    就你而言,你有 generic 像 newType 您需要弄清楚需要将哪种类型作为类型参数传递,并且它应该可以工作。

    阅读以下内容 MSDN docs 有关此主题的详细说明:

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

    乌德帕特:

    您也可以通过以下方式获得泛型类型参数

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

    如果你有一个封闭类型,那么你可以像普通类一样实例化它。请参见以下示例:

    public class GenericClass<Int>
    {
    
    }
    

    现在我们可以生成这样一个实例:

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

    DEMO Fiddle