[C#] 예제와 함께 Activator.CreateInstance의 목적?

누군가 Activator.CreateInstance()목적을 자세히 설명 할 수 있습니까 ?



답변

MyFancyObject아래와 같은 클래스가 있다고 가정합니다 .

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

그것은 당신을 돌릴 수 있습니다 :

String ClassName = "MyFancyObject";

으로

MyFancyObject obj;

사용

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

그런 다음 다음과 같은 작업을 수행 할 수 있습니다.

obj.A = 100;

그것이 그 목적입니다. 또한 Type문자열에 클래스 이름 대신를 제공하는 것과 같은 많은 다른 오버로드가 있습니다. 왜 그런 문제가 발생하는지는 다른 이야기입니다. 필요한 사람들은 다음과 같습니다.


답변

왜 그런 것을 사용하는지 예를 들어 드릴 수 있습니다. 레벨과 적을 XML 파일에 저장하려는 게임을 생각해보십시오. 이 파일을 구문 분석 할 때 다음과 같은 요소가있을 수 있습니다.

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

지금 할 수있는 것은 레벨 파일에있는 오브젝트를 동적으로 생성하는 것입니다.

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

이것은 동적 환경을 구축하는 데 매우 유용합니다. 물론 플러그인이나 애드 인 시나리오 등에 사용할 수도 있습니다.


답변

내 좋은 친구 MSDN 이 예를 들어 설명 할 수 있습니다.

향후 링크 또는 내용이 변경되는 경우 코드는 다음과 같습니다.

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


답변

당신은 또한 이것을 할 수 있습니다-

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


답변

다음은 좋은 예가 될 수 있습니다. 예를 들어 로거 세트가 있고 사용자가 구성 파일을 통해 런타임에서 사용할 유형을 지정할 수 있습니다.

그때:

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

또는 또 다른 경우는 엔티티를 생성하고 DB에서 수신 한 데이터에 의한 엔티티 초기화를 담당하는 공통 엔티티 팩토리가있는 경우입니다.

(의사 코드)

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;
}


답변

그만큼 Activator.CreateInstance 메서드는 지정된 매개 변수와 가장 일치하는 생성자를 사용하여 지정된 형식의 인스턴스를 만듭니다.

예를 들어 유형 이름을 문자열로 사용하고 해당 문자열을 사용하여 해당 유형의 인스턴스를 생성한다고 가정 해 보겠습니다. Activator.CreateInstance이것을 위해 사용할 수 있습니다 .

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

다음은 응용 프로그램을 자세히 설명하는 MSDN 문서입니다.

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


답변

deepee1 및 this 를 기반으로 문자열에서 클래스 이름을 수락 한 다음이를 사용하여 LINQ를 사용하여 데이터베이스에 읽고 쓰는 방법은 다음과 같습니다. deepee1의 캐스팅 대신 “dynamic”을 사용합니다. 속성을 할당 할 수 있기 때문에 원하는 테이블을 동적으로 선택하고 작업 할 수 있습니다.

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);