2011-07-05 1 views
10

속성 (MyProperty)을 가진 객체 (MyObject)가 있습니다. 유형 이름 (예 : String 또는 MyClass 등)을 받고 싶습니다.제네릭 (예 : "Collection`1")을 사용하는 속성의 객체 유형에서 "아포스트로피 + 숫자"의 의미는 무엇입니까?

PropertyInfo propInfo = typeof(MyObject).GetProperty("MyProperty"); 
Console.WriteLine(propInfo.PropertyType.Name); 
Console.WriteLine(propInfo.PropertyType.FullName); 

간단한 유형의 문제가 없습니다 만, MyProperty는 제네릭 형식 인 경우, 나는 이름 (예를 들어, Collection<String>)의지고의 문제를 직면 : 내가 사용합니다. 이는 인쇄 :

Collection`1

System.Collections.ObjectModel.Collection`1 [선택 System.String, mscorlib의 버전 2.0.0.0 = 문화 = 중립 PublicKeyToken = b77a5c561934e089]

무엇입니까? `1? 그리고 "Collection<String>"을 어떻게 얻을 수 있습니까?

+2

Collection'1 1 개 제네릭 형식 매개 변수 –

답변

11

"1"은 1 개의 제네릭 매개 변수가있는 제네릭 형식을 의미합니다. @LukeH에 의해 제안 문자열을 가져 오는

한 가지 방법은 System.CodeDom을 사용하는 것입니다 :

using System; 
using System.CodeDom; 
using System.Collections.Generic; 
using Microsoft.CSharp; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var p = new CSharpCodeProvider()) 
      { 
       var r = new CodeTypeReference(typeof(Dictionary<string, int>)); 

       Console.WriteLine(p.GetTypeOutput(r)); 
      } 
     } 
    } 
} 

다른 방법은 here입니다. @jaredpar의 코드는 아래를 참조하십시오 :

public static string GetFriendlyTypeName(Type type) { 
    if (type.IsGenericParameter) 
    { 
     return type.Name; 
    } 

    if (!type.IsGenericType) 
    { 
     return type.FullName; 
    } 

    var builder = new System.Text.StringBuilder(); 
    var name = type.Name; 
    var index = name.IndexOf("`"); 
    builder.AppendFormat("{0}.{1}", type.Namespace, name.Substring(0, index)); 
    builder.Append('<'); 
    var first = true; 
    foreach (var arg in type.GetGenericArguments()) 
    { 
     if (!first) 
     { 
      builder.Append(','); 
     } 
     builder.Append(GetFriendlyTypeName(arg)); 
     first = false; 
    } 
    builder.Append('>'); 
    return builder.ToString(); 
} 
+0

Nullables를 처리하고 쉼표 뒤에 공백을 추가 할 수 있습니다. – SLaks

+0

전체 소스를 복사하는 경우 JaredPar에 질문에 대한 링크 이상을 신용 할 수 있습니다. – Heinzi

+0

'type.GetGenericTypeDefinition(). FullName' – SLaks

8

이것은 CLR 내부 typename입니다.

숫자는 유형이 오버로드 될 수 있기 때문에 제네릭 형식 매개 변수의 수입니다. CLR은이 C 번호와는 아무 상관이 없기 때문에
, C#을 스타일의 유형 이름을 취득 할 내장 방법은 없습니다

(Func`1Func`2 다른 종류).

+5

와 함께 일반 집합을 의미 당신은 실제로는 C#에서 얻을 수 있습니다 - 스타일 이름을 사용하여 CodeDom,하지만 난 아마 신경 쓰지 않을거야! '(var p = new CSharpCodeProvider()) {var r = new CodeTypeReference (propInfo.PropertyType);를 사용하는 것과 같은 것입니다. Console.WriteLine (p.GetTypeOutput (r)); }' – LukeH

+0

@LukeH : 원본을 보면 배열 만 처리하고 제네릭은 처리하지 않습니다. – SLaks

+0

그것은 던져 버린 모든 제네릭 타입에 대해 작동합니다! – LukeH

0

SLaks 이미 어떤 '한 의미를 설명했다. 당신은 Type.GetGenericArguments를 사용하여 제네릭 형식 매개 변수의 이름을 얻을 수 있습니다 : 두 번째 질문에 대해

if (propInfo.PropertyType.IsGenericType) { 
    Type[] typeArguments = propInfo.PropertyType.GetGenericArguments(); 
    // typeArguments now contains an array of types ({String} in your example). 
} 
+1

그는 유형 매개 변수의 배열이 아닌 문자열을 원합니다. – SLaks

+0

@ SLaks : 좋은 지적입니다.나는 그것을 독자에게 연습으로 남겨 둘 것이다. ;-) – Heinzi