program story

.net의 배열 유형에서 배열 항목 유형을 가져 오는 방법

inputbox 2020. 11. 24. 07:57
반응형

.net의 배열 유형에서 배열 항목 유형을 가져 오는 방법


System.String[]유형 객체 가 있다고 가정 합니다. 유형 객체를 쿼리하여 배열인지 확인할 수 있습니다.

Type t1 = typeof(System.String[]);
bool isAnArray = t1.IsArray; // should be true

그러나 t1에서 배열 항목의 유형 객체를 얻는 방법

Type t2 = ....; // should be typeof(System.String)

Type.GetElementType이 목적으로 인스턴스 메소드 사용할 수 있습니다 .

Type t2 = t1.GetElementType();

[Returns] 현재 배열, 포인터 또는 참조 유형이 포함하거나 참조하는 객체의 유형 또는 현재 유형이 배열 또는 포인터가 아니거나 참조로 전달되지 않거나 제네릭 유형을 나타내는 경우 null 또는 제네릭 형식 또는 제네릭 메서드 정의의 형식 매개 변수


@psaxton 주석 덕분에 Array와 다른 컬렉션의 차이점을 지적했습니다. 확장 방법으로 :

public static class TypeHelperExtensions
{
    /// <summary>
    /// If the given <paramref name="type"/> is an array or some other collection
    /// comprised of 0 or more instances of a "subtype", get that type
    /// </summary>
    /// <param name="type">the source type</param>
    /// <returns></returns>
    public static Type GetEnumeratedType(this Type type)
    {
        // provided by Array
        var elType = type.GetElementType();
        if (null != elType) return elType;

        // otherwise provided by collection
        var elTypes = type.GetGenericArguments();
        if (elTypes.Length > 0) return elTypes[0];

        // otherwise is not an 'enumerated' type
        return null;
    }
}

용법:

typeof(Foo).GetEnumeratedType(); // null
typeof(Foo[]).GetEnumeratedType(); // Foo
typeof(List<Foo>).GetEnumeratedType(); // Foo
typeof(ICollection<Foo>).GetEnumeratedType(); // Foo
typeof(IEnumerable<Foo>).GetEnumeratedType(); // Foo

// some other oddities
typeof(HashSet<Foo>).GetEnumeratedType(); // Foo
typeof(Queue<Foo>).GetEnumeratedType(); // Foo
typeof(Stack<Foo>).GetEnumeratedType(); // Foo
typeof(Dictionary<int, Foo>).GetEnumeratedType(); // int
typeof(Dictionary<Foo, int>).GetEnumeratedType(); // Foo, seems to work against key

그의 좋은 답변에 대한 @drzaus 에게 감사 하지만 한 줄로 압축 할 수 있습니다 ( s 및 유형 확인).nullIEnumerable

public static Type GetEnumeratedType(this Type type) =>
   type?.GetElementType()
   ?? typeof(IEnumerable).IsAssignableFrom(type)
   ? type.GenericTypeArguments.FirstOrDefault()
   : null;

null예외를 피하기 위해 체커를 추가 했지만, 안 될 수도 있습니다 ( Null Conditional Operators를 자유롭게 제거 할 수 있음 ). 또한 함수가 일반 유형이 아닌 컬렉션에서만 작동하도록 필터를 추가했습니다.

그리고 이것은 컬렉션의 주제를 변경하는 구현 된 서브 클래스에 의해 속일 수 있으며 구현자는 컬렉션의 제네릭 유형 인수를 나중 위치로 이동하기로 결정했습니다.

참고 URL : https://stackoverflow.com/questions/4129831/how-do-i-get-the-array-item-type-from-array-type-in-net

반응형