Cel aktywatora.CreateInstance z example?

Czy ktoś może szczegółowo wyjaśnić Activator.CreateInstance() cel?

Author: sll, 2011-09-29

9 answers

Powiedzmy, że masz klasę o nazwie MyFancyObject Jak ta poniżej:

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

Pozwala na obrót:

String ClassName = "MyFancyObject";

Do

MyFancyObject obj;

Użycie

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

I może robić takie rzeczy jak:

obj.A = 100;
To jest jego cel. Ma również wiele innych przeciążeń, takich jak podanie Type zamiast nazwy klasy w łańcuchu. Dlaczego miałbyś mieć taki problem, to już inna historia. Oto kilka osób, które tego potrzebowały:
 117
Author: deepee1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:25

Cóż, mogę dać ci przykład, dlaczego używać czegoś takiego. Pomyśl o grze, w której chcesz przechowywać swój poziom i wrogów w pliku XML. Gdy analizujesz ten plik, możesz mieć taki element jak ten.

<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>

Możesz teraz dynamicznie tworzyć obiekty znalezione w pliku poziomu.

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

Jest to bardzo przydatne do budowania dynamicznych środowisk. Oczywiście możliwe jest również użycie tego do scenariuszy wtyczek lub dodatków i wiele więcej.

 34
Author: dowhilefor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-29 13:43:44

Mój dobry przyjaciel MSDN może Ci to wyjaśnić na przykładzie

Oto kod na wypadek zmiany linku lub treści w przyszłości:

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
 10
Author: Claus Jørgensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 19:01:55

Możesz też to zrobić -

var handle = Activator.CreateInstance("AssemblyName", 
                "Full name of the class including the namespace and class name");
var obj = handle.Unwrap();
 9
Author: William,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-13 18:18:45

Dobrym przykładem może być następny: na przykład masz zestaw loggerów i pozwalasz użytkownikowi określić typ, który ma być używany w trybie runtime za pomocą pliku konfiguracyjnego.

Wtedy:

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

Lub inny przypadek, gdy masz wspólną fabrykę encji, która tworzy encję, a także jest odpowiedzialna za inicjalizację encji przez dane otrzymane z DB:

(pseudocode)

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;
}
 6
Author: sll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 11:16:11

Metoda Activator.CreateInstance tworzy instancję określonego typu za pomocą konstruktora, który najlepiej odpowiada określonym parametrom.

Na przykład, załóżmy, że masz nazwę typu jako łańcuch znaków i chcesz go użyć do utworzenia instancji tego typu. Możesz użyć Activator.CreateInstance do tego:

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

Oto artykuł MSDN, który bardziej szczegółowo wyjaśnia jego zastosowanie:

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

 3
Author: James Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-29 14:06:32

Bazując na deepee1 i this , Oto jak zaakceptować nazwę klasy w łańcuchu znaków, a następnie użyć jej do odczytu i zapisu do bazy danych za pomocą LINQ. Używam" dynamicznego " zamiast odlewania deepee1, ponieważ pozwala mi przypisywać właściwości, co pozwala nam dynamicznie wybierać i działać na dowolnym stole, który chcemy.

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);
 1
Author: DharmaTurtle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-30 21:56:58

Dlaczego miałbyś go używać, skoro już znałeś klasę i zamierzałeś go rzucić? Dlaczego po prostu nie zrobić tego w staromodny sposób i zrobić klasę, jak zawsze to zrobić? Nie ma żadnej przewagi nad tym, jak to się robi normalnie. Czy jest sposób, aby wziąć tekst i operować na nim w ten sposób:

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

Jeśli już wiem, że to Pizza nie ma żadnej przewagi:

p = (Pizza)somefancyjunk("Pizza"); over
Pizza p = new Pizza();
Ale widzę ogromną przewagę magicznej metody, jeśli istnieje.
 0
Author: user8659016,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-23 02:31:56

W połączeniu z odbiciem znalazłem aktywator.CreateInstance jest bardzo pomocny w mapowaniu wyniku procedury składowanej do niestandardowej klasy, jak opisano w następującej odpowiedzi .

 0
Author: usefulBee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-27 22:02:02