Propósito de Activator.CreateInstance con el ejemplo?

¿Alguien puede explicar el propósito de Activator.CreateInstance() en detalle?

Digamos que tiene una clase llamada MyFancyObject como esta a continuación:

 class MyFancyObject { public int A { get;set;} } 

Te permite girar:

 String ClassName = "MyFancyObject"; 

Dentro

 MyFancyObject obj; 

Utilizando

 obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName)) 

y luego puede hacer cosas como:

 obj.A = 100; 

Ese es su propósito. También tiene muchas otras sobrecargas, como proporcionar un Type lugar del nombre de clase en una cadena. Por qué tendrías un problema así es una historia diferente. Aquí hay algunas personas que lo necesitaban:

  • Createinstance () – ¿Estoy haciendo esto bien?
  • C # Usando Activator.CreateInstance
  • Crear un objeto sin conocer el nombre de la clase en el momento del diseño

Bueno, puedo darte un ejemplo de por qué usar algo así. Piensa en un juego en el que quieras almacenar tu nivel y tus enemigos en un archivo XML. Cuando analiza este archivo, es posible que tenga un elemento como este.

  

lo que puedes hacer ahora es crear dinámicamente los objetos encontrados en tu archivo de nivel.

 foreach(XmlNode node in doc) var enemy = Activator.CreateInstance(null, node.Attributes["Type"]); 

Esto es muy útil para construir entornos dynamics. Por supuesto, también es posible usar esto para Plugin o addin scenarios y mucho más.

También puedes hacer esto:

 var handle = Activator.CreateInstance("AssemblyName", "Full name of the class including the namespace and class name"); var obj = handle.Unwrap(); 

Mi buen amigo MSDN puede explicárselo, con un ejemplo

Aquí está el código en caso de que el enlace o contenido cambie en el futuro:

 using System; class DynamicInstanceList { private static string instanceSpec = "System.EventArgs;System.Random;" + "System.Exception;System.Object;System.Version"; public static void Main() { string[] instances = instanceSpec.Split(';'); Array instlist = Array.CreateInstance(typeof(object), instances.Length); object item; for (int i = 0; i < instances.Length; i++) { // create the object from the specification string Console.WriteLine("Creating instance of: {0}", instances[i]); item = Activator.CreateInstance(Type.GetType(instances[i])); instlist.SetValue(item, i); } Console.WriteLine("\nObjects and their default values:\n"); foreach (object o in instlist) { Console.WriteLine("Type: {0}\nValue: {1}\nHashCode: {2}\n", o.GetType().FullName, o.ToString(), o.GetHashCode()); } } } // This program will display output similar to the following: // // Creating instance of: System.EventArgs // Creating instance of: System.Random // Creating instance of: System.Exception // Creating instance of: System.Object // Creating instance of: System.Version // // Objects and their default values: // // Type: System.EventArgs // Value: System.EventArgs // HashCode: 46104728 // // Type: System.Random // Value: System.Random // HashCode: 12289376 // // Type: System.Exception // Value: System.Exception: Exception of type 'System.Exception' was thrown. // HashCode: 55530882 // // Type: System.Object // Value: System.Object // HashCode: 30015890 // // Type: System.Version // Value: 0.0 // HashCode: 1048575 

Un buen ejemplo podría ser el siguiente: por ejemplo, usted tiene un conjunto de Registradores y le permite al usuario especificar el tipo que se utilizará en el tiempo de ejecución a través del archivo de configuración.

Entonces:

 string rawLoggerType = configurationService.GetLoggerType(); Type loggerType = Type.GetType(rawLoggerType); ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger; 

O bien, otro caso es cuando tienes una fábrica de entidades comunes, que crea una entidad, y también es responsable de la inicialización de una entidad por los datos recibidos de la base de datos:

(pseudocódigo)

 public TEntity CreateEntityFromDataRow(DataRow row) where TEntity : IDbEntity, class { MethodInfo methodInfo = typeof(T).GetMethod("BuildFromDataRow"); TEntity instance = Activator.CreateInstance(typeof(TEntity)) as TEntity; return methodInfo.Invoke(instance, new object[] { row } ) as TEntity; } 

El método Activator.CreateInstance crea una instancia de un tipo especificado utilizando el constructor que mejor se ajuste a los parámetros especificados.

Por ejemplo, supongamos que tiene el nombre de tipo como una cadena y desea utilizar la cadena para crear una instancia de ese tipo. Puede usar Activator.CreateInstance para esto:

 string objTypeName = "Foo"; Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName)); 

Aquí hay un artículo de MSDN que explica su aplicación con más detalle:

http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

Partiendo de deepee1 y esto , aquí se muestra cómo aceptar un nombre de clase en una cadena, y luego usarlo para leer y escribir en una base de datos con LINQ. Utilizo “dynamic” en lugar de la conversión de deepee1 porque me permite asignar propiedades, lo que nos permite seleccionar y operar dinámicamente en cualquier tabla que deseemos.

 Type tableType = Assembly.GetExecutingAssembly().GetType("NameSpace.TableName"); ITable itable = dbcontext.GetTable(tableType); //prints contents of the table foreach (object y in itable) { string value = (string)y.GetType().GetProperty("ColumnName").GetValue(y, null); Console.WriteLine(value); } //inserting into a table dynamic tableClass = Activator.CreateInstance(tableType); //Alternative to using tableType, using Tony's tips dynamic tableClass = Activator.CreateInstance(null, "NameSpace.TableName").Unwrap(); tableClass.Word = userParameter; itable.InsertOnSubmit(tableClass); dbcontext.SubmitChanges(); //sql equivalent dbcontext.ExecuteCommand("INSERT INTO [TableNme]([ColumnName]) VALUES ({0})", userParameter); 

¿Por qué lo usarías si ya conocías la clase y la vas a lanzar? ¿Por qué no simplemente hacerlo a la vieja usanza y hacer que la clase siempre lo haga? No hay ventaja en esto sobre la forma en que se hace normalmente. ¿Hay alguna manera de tomar el texto y operar de esta manera?

 label1.txt = "Pizza" Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3); p.method1(); p.method2(); 

Si ya sé que es una Pizza, no hay ventaja para:

 p = (Pizza)somefancyjunk("Pizza"); over Pizza p = new Pizza(); 

pero veo una gran ventaja para el método Magic si existe.

Junto con la reflexión, encontré que Activator.CreateInstance es muy útil para asignar el resultado del procedimiento almacenado a una clase personalizada como se describe en la siguiente respuesta .