How do i use Activator.CreateInstance with strings?

前端 未结 5 1959
礼貌的吻别
礼貌的吻别 2021-02-05 01:48

In my reflection code i hit a problem with my generic section of code. Specifically when i use a string.

var oVal = (object)\"Test\";
var oType = oVal.GetType();         


        
5条回答
  •  我在风中等你
    2021-02-05 02:11

    This is what I use in my projects. As far as needing to create an instantiation of a type of object and not knowing at design time, is rather normal for me. Perhaps you are cycling through object properties and you want to instantiate all of them dynamically. I have many times needed to create then assign values to non instantiated POCO objects... with the below code you can use a string value stored in the DB to instantiate an object as well or instantiate an object stored in a library that is referencing your library - so you can bypass circular reference errors as well... Hope it helps.

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Reflection;
    
    /// 
    /// Instantiates an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate
    /// returns instantiated object
    /// 
    /// 
    /// 
    public static object Create(string typeAssemblyQualifiedName)
    {
      // resolve the type
      Type targetType = ResolveType(typeAssemblyQualifiedName);
      if (targetType == null)
        throw new ArgumentException("Unable to resolve object type: " + typeAssemblyQualifiedName);
    
      return Create(targetType);
    }
    
    /// 
    /// create by type of T
    /// 
    /// 
    /// 
    public static T Create()
    {
      Type targetType = typeof(T);
      return (T)Create(targetType);
    }
    
    /// 
    /// general object creation
    /// 
    /// 
    /// 
    public static object Create(Type targetType)
    {
      //string test first - it has no parameterless constructor
      if (Type.GetTypeCode(targetType) == TypeCode.String)
        return string.Empty;
    
      // get the default constructor and instantiate
      Type[] types = new Type[0];
      ConstructorInfo info = targetType.GetConstructor(types);
      object targetObject = null;
    
      if (info == null) //must not have found the constructor
        if (targetType.BaseType.UnderlyingSystemType.FullName.Contains("Enum"))
          targetObject = Activator.CreateInstance(targetType);
        else
          throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Constructor not found");
      else
        targetObject = info.Invoke(null);
    
      if (targetObject == null)
        throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Unknown Error");
      return targetObject;
    }
    
    /// 
    /// Loads the assembly of an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate
    /// Returns the object type.
    /// 
    /// 
    /// 
    public static Type ResolveType(string typeAssemblyQualifiedName)
    {
      int commaIndex = typeAssemblyQualifiedName.IndexOf(",");
      string className = typeAssemblyQualifiedName.Substring(0, commaIndex).Trim();
      string assemblyName = typeAssemblyQualifiedName.Substring(commaIndex + 1).Trim();
    
      if (className.Contains("[]"))
        className.Remove(className.IndexOf("[]"), 2);
    
      // Get the assembly containing the handler
      Assembly assembly = null;
      try
      {
        assembly = Assembly.Load(assemblyName);
      }
      catch
      {
        try
        {
          assembly = Assembly.LoadWithPartialName(assemblyName);//yes yes this is obsolete but it is only a backup call
        }
        catch
        {
          throw new ArgumentException("Can't load assembly " + assemblyName);
        }
      }
    
      // Get the handler
      return assembly.GetType(className, false, false);
    }
    

提交回复
热议问题