2010-03-02 7 views
19

많은 곳에서 FullTypeName, AssemblyName 형식의 부분적으로 한정된 유형 이름이 발생합니다 (예 : Type.AssemblyQualifiedName). 버전, culture 및 publicKeyToken 한정자가없는 경우에만 가능합니다.부분적으로 한정된 형식 이름이 주어진 경우 Type.GetType은 어떻게 작동합니까?

제 질문은 최소한 Type으로 변환 할 수 있습니까? 나는 Type.GetType이 일을한다고 생각하지만, 슬프게도, 그렇지 않습니다. 다음 코드는, 예를 들어, null 반환 : 물론

Type.GetType("System.Net.Sockets.SocketException, System"); 

, 나는 그것이 작동합니까 완전한 이름을 지정하는 경우 :

Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 

덕분에 많이.

+0

컴파일 타임에 유형이 있습니까? 그렇다면 왜 typeof () .FullName, et. 알았지? 런타임에 유형이있는 경우 .GetType(). FullName 등을 사용할 수 있습니다. al. 아니면 구체적인 요청을 놓치고 있습니까? 부분적인 이름을 지정하기를 원하지만, 타입 시스템보다 로더에 더 많은 것이 있습니다. FQN은 이름 충돌이 발생하는 드문 경우에 대한 참조 문제의 모호성을 없애기위한 것으로, BCL 어셈블리보다 사용자 어셈블리에서 더 자주 사용됩니다. – GrayWizardx

+1

저는 typeof() 또는 Type.FullName을 완벽하게 알고 있습니다. 개체의 형식은 구성 파일에서 읽혀 지므로 Type.GetType을 사용합니다. 이것이 부분적으로 한정된 타입의 이름이 어떻게 작동하는지 이해하는 데 관심이있는 이유입니다. – mark

답변

8

이미있는 DLL이 이미 응용 프로그램 도메인에로드되어 있지 않은 경우 (예 : 사용 된 경우) 이미 이와 같은 전체 경로가 필요합니다. 이미로드 된 경우 더 짧은 버전으로 찾을 수 있습니다.

질문에 대답하려면 : 두 번째 버전은 항상 작동하며 그것에 충실하고 걱정할 방법이 하나 있습니다. 코드는 약식 작업

+1

어셈블리가 이미로드되었는지 여부는 중요하지 않다고 생각합니다. 짧은 버전은 작동하지 않습니다. 형식이 현재 실행중인 어셈블리 또는 mscorlib에 있으면 네임 스페이스로 정규화 된 이름이 작동합니다. 아래 풀러 설명. – lesscode

2

은 다음과 같습니다

Assembly a = Assembly.LoadWithPartialName(assemblyName); 
    Type t = a.GetType(typeName); 

하지만 LoadWithPartialName이되지 않습니다, 그래서 당신은 긴 양식 충실해야한다고 생각한다. 어셈블리가 현재 도메인에로드 된 경우

29

다음 일반적으로 아래의 코드는 작동합니다

public static Type GetTypeEx(string fullTypeName) 
{ 
    return Type.GetType(fullTypeName) ?? 
      AppDomain.CurrentDomain.GetAssemblies() 
        .Select(a => a.GetType(fullTypeName)) 
        .FirstOrDefault(t => t != null); 
} 

당신은 너무처럼 사용할 수 있습니다

Type t = GetTypeEx("System.Net.Sockets.SocketException"); 
+1

답장을 보내 주셔서 감사합니다. 정확히 내가 찾고 있었던 것입니다. "받아 들인"대답보다 훨씬 낫습니다. –

+2

이것은 매우 느릴 수 있으므로 캐시하지 말아야한다는 것을 기억하십시오. – nawfal

2

은 유사한 문제를 가진 겪었 데 일부 레거시 코드, 나는 받아 들인 대답의 첫 문장이 정확하다고 생각하지 않는다. 어셈블리가 이미로드되었는지 여부는 중요하지 않습니다. 문제의 유형, 현재 실행중인 어셈블리 또는 mscorlib에 인 경우에 네임 스페이스 형명 모든 것을이 필요한 경우를 제외하고

는 문서에 따르면, Type.GetType(string)AssemblyQualifiedName을 필요로한다.

AssemblyQualifiedName에는 형식 어셈블리의 전체 DisplayName (버전, 문화권 및 공개 키 토큰 포함)이 포함됩니다.

사용자 정의 AssemblyResolver으로 실패한 유형로드를 차단하지 않으면 짧은 버전이 작동하지 않습니다 (실제로 다른 문제를 마스킹하는 경우).

0

사실, Type.GetType (string)에는 AssemblyQualifiedName이 필요합니다.이것은 여러 형태로 할 수있다 : 다음

MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 

도 유효 AssemblyQualifiedNames 있습니다 : 서명 된 어셈블리

MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly 

하는 FullyQualifiedAssemblyName에 필요한 최소입니다를 들어

MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 

서명되지 않은 어셈블리 인 경우 FullyQualifiedAssemblyName에 필요한 최소값은 다음과 같습니다.

MyNS.MyType, MyAssembly 

다른 사람들이 제공 한 코드 조각에서 진행되는 "손 흔들기"가 필요하지 않습니다. 유형 이름이 올바르게 설정되었는지 확인하고 유연성에 따라 유형에 액세스하고 어셈블리를 동적으로로드 할 수 있습니다. 나는 이것을 정기적으로한다. 사용 OP의 예에서

: 실패

Type.GetType("System.Net.Sockets.SocketException, System") 

이유는 PublicKeyToken의 부재였다. .Net FW 어셈블리는 모두 서명되어 있으므로 어셈블리 이름을 확인하려면 PublicKeyToken이 필요합니다. 다음은 작동합니다 :

Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089") 
관련 문제