문자열에서 클래스의 인스턴스를 만듭니다.


218

런타임에 클래스 이름을 알고 있다는 사실을 기반으로 클래스 인스턴스를 만드는 방법이 있습니까? 기본적으로 나는 클래스의 이름을 문자열로 가질 것입니다.


구현하려는 솔루션을 설명했지만 해결하려는 문제는 설명하지 않은 것 같습니다. 아마도 확장 성으로 무언가를 시도하고있을 것입니다.이 경우 Managed Extensibility Framework 를 확인하는 것이 좋습니다 .
Jay Bazuzi

답변:


159

Activator.CreateInstance 메소드를 살펴보십시오 .


15
훌륭한 예와 관련 : stackoverflow.com/questions/493490/…
John S.

또한이 게시물은 귀하의 유형을 찾아야하기 때문에 관련이 있습니다 : stackoverflow.com/questions/1825147/…
Brad Parks


4
예 :var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Endy Tjahjono

2
여기서 중요한 참고 사항 : .Unwrap ()은 원격 핸들을지나 실제로 캐스트를 수행 할 수 있습니다. @Endy-감사합니다
Roger Willcocks

77

꽤 간단합니다. 당신의 클래스 명이라고 가정 Car및 네임 스페이스가되어 Vehicles, 다음과 같이 매개 변수를 전달할 Vehicles.Car반환 타입의 객체 어느 Car. 이와 같이 모든 클래스의 인스턴스를 동적으로 만들 수 있습니다.

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}

귀하의 경우 정규화 된 이름 (즉, Vehicles.Car이 경우) 조립 서로에의는 Type.GetTypenull가됩니다. 이러한 경우 모든 어셈블리를 반복하고를 찾습니다 Type. 이를 위해 아래 코드를 사용할 수 있습니다

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

이제 매개 변수화 된 생성자 를 호출 하려면 다음을 수행하십시오.

Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type

대신에

Activator.CreateInstance(t);

캐스팅하지 않고 사용하는 방법과 주어진 문자열에서 캐스팅을 수행하는 방법 ??
TaW

1
@TaW-클래스 인스턴스를 사용하려면 수행 할 작업에 대한 지식이 필요합니다. 그렇지 않으면 사용할 수 없습니다. 가장 일반적인 사용 사례는 사전 정의 된 계약을 제공하는 일부 인터페이스로 전송하는 것입니다. (당신이 사용하지 않는이 보유하고 dynamic코드를 - 참조 stackoverflow.com/a/2690661/904521을 )
토 메르 Cagan

1
그것의 이름으로 변수의 유형을 인코딩하지 마십시오, 예를 들면 :. 접두사 필요가 없습니다 strFullyQualifiedName으로 str, fullyQualifiedName일을 할 것입니다.
Mehdi Dehghani

키워드 str는 변수 명명 규칙의 일부로 사용됩니다. 어떤 조직과 프로젝트는 이것을 따라야한다고 주장했습니다. 특정 오라 간화 / 프로젝트에서 일했을 경우, 이것을 알게 될 것입니다. 당신이 str또한 없이 말한대로 그것은 일을 할 것입니다 :) @MehdiDehghani
Sarath Avanavu

1
헝가리어 표기법으로 알려진 명명법에 대해 알기 위해 어떤 조직에서도 일할 필요가 없으며, 이는 나쁘고 사용되지 않는 명명법 중 하나입니다 . 특히 C 번호
메디 Dehghani

55

이 방법을 성공적으로 사용했습니다.

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)

반환 된 객체를 원하는 객체 유형으로 캐스트해야합니다.


9
클래스 이름을 통해 객체를 만든 다음 해당 유형으로 캐스팅하면 전혀 의미가없는 시나리오를 상상하려고합니다.
MusiGenesis

13
무슨 말인지 알 겠어 중복되는 것 같습니다. 클래스 이름을 알고 있다면 왜 동적 문자열이 필요합니까? 한 가지 상황은 기본 클래스로 캐스팅하고 문자열이 해당 기본 클래스의 자손을 나타내는 것일 수 있습니다.
Ray Li

4
기본 클래스가 알려진 경우 기본 클래스 또는 해당 인터페이스를 인수로 사용하여 리플렉션없이 하위 항목을 전달할 수 있습니다.
Garet Claborn

3
유용한 시나리오 : 직렬화 인터페이스 또는 다른 일반적인 인터페이스 만 있으면됩니다. 수업에 출연하지는 않지만 최소한 객체 이상으로
만들면됩니다.

2
주어진 문자열에서 캐스트를 수행하는 방법 ??
TaW

23

아마도 내 질문은 더 구체적이었을 것입니다. 실제로 문자열의 기본 클래스를 알고 있으므로 다음과 같이 해결했습니다.

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

Activator.CreateInstance 클래스에는 여러 가지 방법으로 동일한 것을 달성하기위한 다양한 메소드가 있습니다. 나는 그것을 물건에 던질 수 있었지만 위의 상황은 내 상황에 가장 많이 사용됩니다.


4
질문 섹션에 응답하는 대신 질문을 편집하고 변경 사항을 기록해 두는 것이 좋습니다. 당신은 더 많은 / 더 나은 답변을 얻을 것이다.
Jason Jackson

귀하에게 맞는 특정 코드 줄을 게시 해 주셔서 감사합니다. 모든 CreateInstance 오버로드와 유형을 생성하는 다른 방법을 정렬하는 데 많은 시간이 걸리고 저를 구했습니다.
Ethel Evans

4

나는 게임에 늦었다는 것을 알고 있지만 ... 당신이 찾고있는 해결책은 위의 조합이며 인터페이스를 사용하여 공개적으로 액세스 가능한 측면을 정의하는 것일 수 있습니다.

그런 다음이 방법으로 생성 된 모든 클래스가 해당 인터페이스를 구현하면 인터페이스 유형으로 캐스트하고 결과 객체로 작업 할 수 있습니다.


4

솔루션의 다른 프로젝트에서 클래스 인스턴스를 작성하려면 클래스 이름 (예 : BaseEntity)으로 표시된 어셈블리를 가져 와서 새 인스턴스를 작성할 수 있습니다.

  var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");

3

예를 들어, 데이터베이스 필드 (문자열로 저장 됨)에 다양한 유형의 값을 저장하고 유형 이름 (예 : String, bool, int, MyClass)을 가진 다른 필드가있는 경우 해당 필드 데이터에서 위의 코드를 사용하여 모든 유형의 클래스를 작성하고 첫 번째 필드의 값으로 채우십시오. 이것은 물론 문자열을 올바른 유형으로 구문 분석하는 방법을 사용하여 저장하는 유형에 따라 다릅니다. 나는 이것을 데이터베이스에 사용자 환경 설정을 저장하기 위해 여러 번 사용했습니다.


-11
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

왜 이런 코드를 작성하고 싶습니까? 'ReportClass'클래스를 사용할 수있는 경우 아래와 같이 직접 인스턴스화 할 수 있습니다.

ReportClass report = new ReportClass();

코드 ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));필요한 클래스를 사용할 수 없지만 코드를 동적으로 인스턴스화하거나 호출하려는 경우 가 사용됩니다.

어셈블리를 알 때 유용하지만 코드를 작성하는 동안 클래스를 ReportClass사용할 수는 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.