type new how from example c# .net reflection activator

how - new gettype c#



¿Cómo uso Activator.CreateInstance con cadenas? (5)

En mi código de reflexión encontré un problema con mi sección genérica de código. Específicamente cuando uso una cadena.

var oVal = (object)"Test"; var oType = oVal.GetType(); var sz = Activator.CreateInstance(oType, oVal);

Excepción

An unhandled exception of type ''System.MissingMethodException'' occurred in mscorlib.dll Additional information: Constructor on type ''System.String'' not found.

Probé esto para propósitos de prueba y también ocurre en este revestimiento único.

var sz = Activator.CreateInstance("".GetType(), "Test");

originalmente escribí

var sz = Activator.CreateInstance("".GetType());

pero me sale este error

Additional information: No parameterless constructor defined for this object.

¿Cómo creo una cadena usando la reflexión?


Esto es lo que uso en mis proyectos. En lo que respecta a la necesidad de crear una instanciación de un tipo de objeto y no saber en el momento del diseño, es bastante normal para mí. Tal vez esté pasando por las propiedades de los objetos y quiera crear una instancia de todos ellos dinámicamente. Muchas veces he necesitado crear y luego asignar valores a objetos POCO no instanciados ... con el siguiente código puede usar un valor de cadena almacenado en la base de datos para crear una instancia de un objeto o crear una instancia de un objeto almacenado en una biblioteca que hace referencia a su biblioteca - para que también pueda evitar los errores de referencia circular ... Espero que ayude.

using System; using System.Collections.Generic; using System.Globalization; using System.Reflection; /// <summary> /// Instantiates an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate /// returns instantiated object /// </summary> /// <param name="typeName"></param> /// <returns></returns> 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); } /// <summary> /// create by type of T /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T Create<T>() { Type targetType = typeof(T); return (T)Create(targetType); } /// <summary> /// general object creation /// </summary> /// <param name="targetType"></param> /// <returns></returns> 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; } /// <summary> /// Loads the assembly of an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate /// Returns the object type. /// </summary> /// <param name="typeString"></param> /// <returns></returns> 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); }


La cadena en realidad no tiene un constructor que tome una cadena como entrada. Hay un constructor que toma una matriz de caracteres así que esto debería funcionar:

var sz = Activator.CreateInstance ("".GetType (), "Test".ToCharArray ());


Parece que estás intentando llamar a un constructor que solo toma una cadena, y no existe tal constructor. Si ya tienes una cadena, ¿por qué estás tratando de crear una nueva? (Cuando no proporcionó ningún otro argumento, estaba intentando llamar a un constructor sin parámetros, lo que, de nuevo, no existe).

Tenga en cuenta que typeof(string) es una forma más sencilla de obtener una referencia al tipo de cadena.

¿Podría darnos más información sobre el panorama general de lo que está tratando de hacer?


Tenga en cuenta que la clase de cadena es inmutable. No se puede cambiar una vez creado. Eso explica por qué no tiene un constructor sin parámetros, nunca podría generar un objeto de cadena útil que no sea una cadena vacía. Eso ya está disponible en el lenguaje C #, es "".

El mismo razonamiento se aplica a un constructor de cadena (cadena). No tiene sentido duplicar una cadena, la cadena que pasaría al constructor ya es una instancia perfectamente buena de la cadena.

Así que arregla tu problema probando el caso de la cadena:

var oType = oVal.GetType(); if (oType == typeof(string)) return oVal as string; else return Activator.CreateInstance(oType, oVal);


Usted está tratando de hacer esto:

var sz = new string();

Intenta compilarlo, entenderás tu error.

Puedes intentar:

var sz = Activator.CreateInstance(typeof(string), new object[] {"value".ToCharArray()});

Pero parece inútil, deberías usar directamente el valor ...