누군가 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 문서입니다.
답변
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);