Soru Array Öğesi Türünü .net'te Array Türü'nden nasıl alabilirim


Benim bir tane var System.String[] nesne yazın. Bir dizi olup olmadığını belirlemek için tip nesnesini sorgulayabilirim

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

Ancak, t1'den dizi nesnesinin bir tür nesnesini nasıl alabilirim

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

56
2017-11-09 01:54


Menşei




Cevaplar:


Örnek yöntemini kullanabilirsiniz Type.GetElementType bu amaç için.

Type t2 = t1.GetElementType();

Geçerli dizi, işaretçi veya referans türü tarafından kapsanan veya başvurulan nesnenin türünü veya geçerli Tür bir dizi veya işaretçi olmadığında veya referans ile geçirilmediyse veya bir genel türü temsil ediyorsa, null [döndürür] veya jenerik tip veya jenerik yöntem tanımında bir tip parametresi.


92
2017-11-09 01:58



Chrrrrrrrrrrrrrrrrrrrr Bro !. Bir milyona teşekkürler. - Preet Sangha
Bu, orijinal olarak sorgulandığı gibi Diziler için çalışır. Referans için, koleksiyon içerdiği türlere tip.GetGenericArguments () [0] olarak erişilebilir. - psaxton
Bağlantınızdaki Açıklamalar "Bu yöntem geri döndü null için Array sınıf "Bu sadece üzerinde çalışabilir T[] formlar. Ama benim testimde iyi görünüyor. Array tarafından oluşturuldu Array.CreateInstance()... - Mr. Ree


@Psaxton adına teşekkürler yorum Yap Array ve diğer koleksiyonlar arasındaki farkı işaret ediyor. Bir uzantı yöntemi olarak:

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;
    }
}

Kullanımı:

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

12
2018-02-24 18:21



Burada küçük bir sorun görüyorum, ya Colleciton veya array olmayan Jenerik ile ilgili sınıflar. Ben denklemi (type.IsArray || type.FullName.StartsWith ("System.Collections")) ekledim. - André
@ André bir örnek nedir? özel sınıf mı demek istiyorsun? çünkü, sayılan bir türse, (?) IEnumerable; belki 'koleksiyonları' kullanmam o zaman 'sayılabilir' olmalıydı? - drzaus
@ André, tip isimlerini karşılaştırmaz, bunun yerine typeof(IEnumerable).IsAssinableFrom(type). - Shimmy
@drzaus, ne tür bir jenerik tipi kontrol edersek, bir IEnumerable, Örneğin IObservable<T>, ya da her neyse. Yöntem tipini GetGenericType. - Shimmy


Sayesinde @drzaus onun için güzel Cevapancak bir oneliner'a sıkıştırılabilir nulls ve IEnumerable ) Türü:

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

Katma null istisnai önlemek için dama, belki de olmamalıdır Boş Koşullu Operatörler). Ayrıca, bir filtre eklendiğinden, işlev yalnızca genel türlerde değil, koleksiyonlarda çalışır.

Ve bunun, koleksiyonun konusunu değiştiren uygulamalı alt sınıflar tarafından da kandırılabileceğini ve uygulayıcının koleksiyonun jenerik-türü argümanını daha sonraki bir konuma taşımayı kararlaştırdığını aklınızda bulundurun.


1
2018-05-07 00:02