주어진 값이 일반 목록인지 어떻게 확인합니까?


89
public bool IsList(object value)
    {
        Type type = value.GetType();
        // Check if type is a generic list of any type
    }

주어진 개체가 목록인지 또는 목록으로 캐스팅 될 수 있는지 확인하는 가장 좋은 방법은 무엇입니까?


아마 당신은 여기에서 답을 찾을 수 stackoverflow.com/questions/755200/...
막심 Kondratyuk

답변:


93
using System.Collections;

if(value is IList && value.GetType().IsGenericType) {

}

4
이것은 작동하지 않습니다-다음 예외가 발생합니다-값은 IList입니다 일반 유형 'System.Collections.Generic.IList <T>'사용시 '1'유형 인수가 필요합니다.

15
System.Collections를 사용하여 추가해야합니다. 소스 파일 위에. 내가 제안한 IList 인터페이스는 일반 버전이 아닙니다 (따라서 두 번째 확인)
James Couvares

1
네가 옳아. 이것은 매력처럼 작동합니다. 내 Watch 창에서 이것을 테스트하고 누락 된 네임 스페이스에 대한 모든 것을 잊었습니다. 저는이 솔루션을 더 좋아하고 매우 간단합니다

3
이것은 작동하지 않습니다. 4.0 IList <T>! = IList? 어쨌든, 그것이 제네릭인지 IEnumerable인지 확인한 다음 확인하고 싶은 속성 "Count"가 있는지 확인해야했습니다. 이 약점이 부분적으로 WCF가 모든 List <T>를 T []로 바꾸는 이유라고 생각합니다.

1
@Edza 올바르지 않습니다. 이것은 일반적으로 부터 작동 List<T>ObservableCollection<T>구현 IList.
HappyNomad jul.

121

확장 메서드 사용을 즐기는 여러분을 위해 :

public static bool IsGenericList(this object o)
{
    var oType = o.GetType();
    return (oType.IsGenericType && (oType.GetGenericTypeDefinition() == typeof(List<>)));
}

따라서 다음과 같이 할 수 있습니다.

if(o.IsGenericList())
{
 //...
}

3
.Net Core의 경우 약간 수정해야합니다return oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

매력처럼 작동합니다! 객체가 아닌 유형 만 가지고 있다면 이것은 당신을 위해 작동합니다! 감사!!
gatsby

IList<>대신 확인 하는 것이 더 안전할까요?
nl-x

14
 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));

6
public bool IsList(object value) {
    return value is IList 
        || IsGenericList(value);
}

public bool IsGenericList(object value) {
    var type = value.GetType();
    return type.IsGenericType
        && typeof(List<>) == type.GetGenericTypeDefinition();
}

5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}

getType ()에 대한 호출이 필요하다고 생각합니다. 예 : value.GetType (). GetGenericArguments (). Length> 0
ScottS

4

Victor Rodrigues의 답변에 따라 제네릭에 대한 또 다른 방법을 고안 할 수 있습니다. 실제로 원래 솔루션은 두 줄로만 줄일 수 있습니다.

public static bool IsGenericList(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}

public static bool IsGenericList<T>(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}

3

다음은 .NET Standard에서 작동하고 인터페이스에 대해 작동하는 구현입니다.

    public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
    {
        return type
            .GetTypeInfo()
            .ImplementedInterfaces
            .Any(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == interfaceType);
    }

다음은 테스트 (xunit)입니다.

    [Fact]
    public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
    }

    [Fact]
    public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
    }

1

다음 코드를 사용하고 있습니다.

public bool IsList(Type type) => IsGeneric(type) && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );

0

아마도 가장 좋은 방법은 다음과 같이하는 것입니다.

IList list = value as IList;

if (list != null)
{
    // use list in here
}

이를 통해 최대한의 유연성을 제공하고 IList인터페이스 를 구현하는 다양한 유형으로 작업 할 수 있습니다 .


3
이것은 요청한 일반 목록 인지 확인하지 않습니다 .
Lucas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.