누군가 Activator.CreateInstance()
목적을 자세히 설명 할 수 있습니까 ?
c#.net
수행하는 방법 Object xyz = Class.forName(className).newInstance();
.
누군가 Activator.CreateInstance()
목적을 자세히 설명 할 수 있습니까 ?
c#.net
수행하는 방법 Object xyz = Class.forName(className).newInstance();
.
답변:
MyFancyObject
아래와 같은 클래스가 있다고 가정합니다 .
class MyFancyObject
{
public int A { get;set;}
}
그것은 당신을 돌릴 수 있습니다 :
String ClassName = "MyFancyObject";
으로
MyFancyObject obj;
사용
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
그런 다음 다음과 같은 작업을 수행 할 수 있습니다.
obj.A = 100;
그것이 그 목적입니다. 또한 Type
문자열에 클래스 이름 대신를 제공하는 것과 같은 많은 다른 오버로드가 있습니다. 왜 그런 문제가 발생하는지는 다른 이야기입니다. 필요한 사람들은 다음과 같습니다.
String ClassName = "My.Namespace.MyFancyObject";
.
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
있지만 유형으로 캐스팅하는 대신. ClassName에서 만든 유형으로 캐스트 하시겠습니까? 이렇게 Type type = Type.GetType(ClassName);obj = (type )Activator.CreateInstance("MyAssembly", ClassName))
?
왜 그런 것을 사용하는지 예를 들어 드릴 수 있습니다. 레벨과 적을 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();
.Unwrap()
정확히 무엇을 하고 이것이 다른 솔루션과 어떻게 관련되는지 에 대한 추가 설명을 제공 할 수 있습니까?
CreateInstance
그것이 반환 하는 곳 의 다른 과부하에 System.Runtime.Remoting.ObjectHandle
있습니다.
다음은 좋은 예가 될 수 있습니다. 예를 들어 로거 세트가 있고 사용자가 구성 파일을 통해 런타임에서 사용할 유형을 지정할 수 있습니다.
그때:
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;
}
typeof(loggerType)
에 결과를loggerType is a variable and used like a type
그만큼 Activator.CreateInstance
메서드는 지정된 매개 변수와 가장 일치하는 생성자를 사용하여 지정된 형식의 인스턴스를 만듭니다.
예를 들어 유형 이름을 문자열로 사용하고 해당 문자열을 사용하여 해당 유형의 인스턴스를 생성한다고 가정 해 보겠습니다. Activator.CreateInstance
이것을 위해 사용할 수 있습니다 .
string objTypeName = "Foo";
Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
다음은 응용 프로그램을 자세히 설명하는 MSDN 문서입니다.
new Foo()
. 나는 OP가 더 현실적인 예를 원했다고 생각합니다.
CreateInstance
는 디자인 타임에 인스턴스화 할 개체 유형을 모르는 경우입니다. 이 예에서는 type Foo
으로 캐스팅하고 있으므로 유형 임을 분명히 알 수 Foo
있습니다. 당신이 할 수 있기 때문에 당신은 결코 이것을하지 않을 것 Foo foo = new Foo()
입니다.
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);
이미 클래스를 알고 있고 캐스팅 할 예정이라면 왜 사용하겠습니까? 그냥 구식으로하고 항상 수업을하는 것처럼 만드는 게 어떨까요? 일반적으로 수행되는 방식에 비해 이점이 없습니다. 텍스트를 가져와 이에 따라 작동하는 방법이 있습니까?
label1.txt = "Pizza"
Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);
p.method1();
p.method2();
이미 피자를 알고 있다면 다음과 같은 이점이 없습니다.
p = (Pizza)somefancyjunk("Pizza"); over
Pizza p = new Pizza();
하지만 매직 방법이 존재한다면 큰 장점이 있습니다.
CreateInstance(Type type)
가CreateInstance<T>()
과부하 와 일치 하는 것이 좋습니다 .