¿Alguien puede explicar el Activator.CreateInstance()
propósito en detalle?
c#.net
forma de hacerlo Object xyz = Class.forName(className).newInstance();
.
¿Alguien puede explicar el Activator.CreateInstance()
propósito en detalle?
c#.net
forma de hacerlo Object xyz = Class.forName(className).newInstance();
.
Respuestas:
Digamos que tiene una clase llamada MyFancyObject
como esta a continuación:
class MyFancyObject
{
public int A { get;set;}
}
Te permite convertir:
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
nombre en lugar del nombre de la clase en una cadena. Por qué tendría un problema así es una historia diferente. Aquí hay algunas personas que lo necesitaban:
String ClassName = "My.Namespace.MyFancyObject";
).
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
pero en lugar de lanzar con el tipo? ¿Reparto con tipo hecho desde ClassName? Me gusta esto Type type = Type.GetType(ClassName);obj = (type )Activator.CreateInstance("MyAssembly", ClassName))
?
Bueno, puedo darte un ejemplo de por qué usar algo así. Piensa en un juego donde quieras almacenar tu nivel y tus enemigos en un archivo XML. Cuando analiza este archivo, es posible que tenga un elemento como este.
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
lo que puede hacer ahora es crear dinámicamente los objetos encontrados en su archivo de nivel.
foreach(XmlNode node in doc)
var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
Esto es muy útil para construir entornos dinámicos. Por supuesto, también es posible usar esto para escenarios de complementos o complementos y mucho más.
Mi buen amigo MSDN te lo puede explicar, con un ejemplo
Aquí está el código en caso de que el enlace o el contenido cambien 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
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();
.Unwrap()
hace precisamente y cómo se relaciona esto con otras soluciones?
CreateInstance
donde regresa System.Runtime.Remoting.ObjectHandle
.
Un buen ejemplo podría ser el siguiente: por ejemplo, tiene un conjunto de registradores y permite al usuario especificar el tipo que se utilizará en tiempo de ejecución a través del archivo de configuración.
Luego:
string rawLoggerType = configurationService.GetLoggerType();
Type loggerType = Type.GetType(rawLoggerType);
ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
O otro caso es cuando tiene 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 DB:
(pseudocódigo)
public TEntity CreateEntityFromDataRow<TEntity>(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;
}
typeof(loggerType)
resultados enloggerType is a variable and used like a type
El Activator.CreateInstance
método crea una instancia de un tipo especificado utilizando el constructor que mejor coincide con los parámetros especificados.
Por ejemplo, supongamos que tiene el nombre del tipo como una cadena y desea usar la cadena para crear una instancia de ese tipo. Podrías 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:
new Foo()
. Creo que el OP quería un ejemplo más realista.
CreateInstance
es si no conoce el tipo de objeto que va a instanciar en el momento del diseño. En este ejemplo, claramente sabe que es de tipo, Foo
ya que lo está convirtiendo como tipo Foo
. Nunca harías esto porque solo puedes hacerlo Foo foo = new Foo()
.
Partiendo de deepee1 y esto , aquí se explica cómo aceptar un nombre de clase en una cadena y luego usarlo para leer y escribir en una base de datos con LINQ. Uso "dinámico" en lugar de la conversión de deepee1 porque me permite asignar propiedades, lo que nos permite seleccionar dinámicamente y operar en cualquier tabla que queramos.
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 ibas a lanzar? ¿Por qué no simplemente hacerlo a la antigua usanza y hacer que la clase como siempre lo hagas? Esto no tiene ninguna ventaja sobre la forma en que se hace normalmente. ¿Hay alguna manera de tomar el texto y operarlo 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, descubrí que Activator.CreateInstance es muy útil para asignar el resultado del procedimiento almacenado a una clase personalizada como se describe en la siguiente respuesta .
CreateInstance(Type type)
coincida con laCreateInstance<T>()
sobrecarga.