[c#] 문자열 표현에서 제네릭 유형을 어떻게 얻을 수 있습니까?

나는 MyClass<T>.

그리고 나는 이것을 가지고 있습니다 string s = "MyClass<AnotherClass>";. 문자열에서 유형을 어떻게 얻을 수 s있습니까?

한 가지 방법 (못생긴)은 “<“및 “>”를 구문 분석하고 다음을 수행하는 것입니다.

Type acType = Type.GetType("AnotherClass");
Type whatIwant = typeof (MyClass<>).MakeGenericType(acType);

그러나 구문 분석 등을 수행하지 않고 최종 유형을 얻는 더 깨끗한 방법이 있습니까?



답변

제네릭형식 은 이름,`문자, 유형 매개 변수 수, 쉼표로 구분 된 괄호로 구분 된 유형 목록입니다.

Type.GetType("System.Collections.Generic.IEnumerable`1[System.String]");

제네릭의 C # 구문에서 CLR이 원하는 종류의 문자열로 쉽게 변환 할 수있는 방법이 있는지 잘 모르겠습니다. 질문에서 언급 한 것처럼 구문 분석을 위해 빠른 정규식을 작성하기 시작했지만 유형 매개 변수로 중첩 된 제네릭을 갖는 기능을 포기하지 않으면 구문 분석이 매우 복잡해질 것임을 깨달았습니다.


답변

체크 아웃 Activator.CreateInstance-당신은 유형으로 부를 수 있습니다

Activator.CreateInstance(typeof(MyType))

또는 어셈블리 및 유형 이름을 string

Activator.CreateInstance("myAssembly", "myType")

그러면 필요한 유형의 인스턴스가 제공됩니다.

Type인스턴스 가 아니라 필요한 경우 Type.GetType()메서드와 관심있는 유형의 정규화 된 이름을 사용합니다. 예 :

string s = "System.Text.StringBuilder";
Type myClassType = Type.GetType(s);

그것은 당신에게 Type문제를 줄 것 입니다.


답변

나는 이와 같은 것이 필요했고 필요한 간단한 유형 이름을 구문 분석하기 위해 코드를 작성했습니다. 물론, 같은 제네릭 유형 이름을 식별하지 않기 때문에 개선의 여지가 List<string>있지만 string, int[]등에서 는 괜찮습니다 decimal?. 이것이 누구에게나 도움이 될 경우 공유합니다.

public static class TypeExtensions
{
  public static Type GetTypeFromSimpleName(string typeName)
  {
    if (typeName == null)
      throw new ArgumentNullException("typeName");

    bool isArray = false, isNullable = false;

    if (typeName.IndexOf("[]") != -1)
    {
      isArray = true;
      typeName = typeName.Remove(typeName.IndexOf("[]"), 2);
    }

    if (typeName.IndexOf("?") != -1)
    {
      isNullable = true;
      typeName = typeName.Remove(typeName.IndexOf("?"), 1);
    }

    typeName = typeName.ToLower();

    string parsedTypeName = null;
    switch (typeName)
    {
      case "bool":
      case "boolean":
        parsedTypeName = "System.Boolean";
        break;
      case "byte":
        parsedTypeName = "System.Byte";
        break;
      case "char":
        parsedTypeName = "System.Char";
        break;
      case "datetime":
        parsedTypeName = "System.DateTime";
        break;
      case "datetimeoffset":
        parsedTypeName = "System.DateTimeOffset";
        break;
      case "decimal":
        parsedTypeName = "System.Decimal";
        break;
      case "double":
        parsedTypeName = "System.Double";
        break;
      case "float":
        parsedTypeName = "System.Single";
        break;
      case "int16":
      case "short":
        parsedTypeName = "System.Int16";
        break;
      case "int32":
      case "int":
        parsedTypeName = "System.Int32";
        break;
      case "int64":
      case "long":
        parsedTypeName = "System.Int64";
        break;
      case "object":
        parsedTypeName = "System.Object";
        break;
      case "sbyte":
        parsedTypeName = "System.SByte";
        break;
      case "string":
        parsedTypeName = "System.String";
        break;
      case "timespan":
        parsedTypeName = "System.TimeSpan";
        break;
      case "uint16":
      case "ushort":
        parsedTypeName = "System.UInt16";
        break;
      case "uint32":
      case "uint":
        parsedTypeName = "System.UInt32";
        break;
      case "uint64":
      case "ulong":
        parsedTypeName = "System.UInt64";
        break;
    }

    if (parsedTypeName != null)
    {
      if (isArray)
        parsedTypeName = parsedTypeName + "[]";

      if (isNullable)
        parsedTypeName = String.Concat("System.Nullable`1[", parsedTypeName, "]");
    }
    else
      parsedTypeName = typeName;

    // Expected to throw an exception in case the type has not been recognized.
    return Type.GetType(parsedTypeName);
  }
}

이것을 사용하는 것은 다음과 같이 작성하는 것만 큼 간단합니다.

Type t;

t = TypeExtensions.GetTypeFromSimpleName("string");
t = TypeExtensions.GetTypeFromSimpleName("int[]");
t = TypeExtensions.GetTypeFromSimpleName("decimal?");


답변

문자열에서 유형 객체를 가져 오려면 다음을 사용하십시오.

Type mytype = Type.GetType(typeName);

그런 다음 이것을 다음으로 전달할 수 있습니다 Activator.CreateInstance().

Activator.CreateInstance(mytype);


답변

비슷한 답변을 본 것 같지만 이것을 파싱 할 시간이 많지 않습니다. 특히, 나는 그들이 여기서 당신이 원하는 것을 정확히하고 있다고 생각합니다.

Entity Framework 일반 리포지토리 오류

(String.Format("[{0}]", baseType.Name.ToString())).OfType<T>();

도움이 되었기를 바랍니다. 그렇지 않은 경우 더 구체적으로 알려주세요.


답변