Question

J'ai plusieurs classes, que tout découle de superclasse.

Quand les classes sont créées, ils sont tous mis dans une liste (de SuperClass). Quand je vais dans la liste, je voudrais downcaster l'objet SuperClass à son baseObject, et le mettre dans la liste correcte. (J'ai une liste créée pour chacun des sous-types de SuperClass).

Il est possible de determin:

 If TypeOf SuperClass Is SubClass Then
      listOfSubClass.Add(DirectCast(SuperCLass, SubClass)
 End If

mais cela est beaucoup de travail, quand il y a plusieurs classes.

En utilisant

SuperClass.GetType.FullName

Je reçois le type de subClass.

Ma question est: Est-il possible d'utiliser pour lancer dynamiquement l'objet SuperClass? en psudoCode:

For each SuperClass
     Dim temp As SuperClass.GetType.FullName = _
                       DirectCast(SuperCLass, SuperClass.GetType.FullName 
     list.add(temp)
Next

Edit: J'espérais que je pouvais utiliser une variable au lieu de créer un cas pour chaque SubClass et de le faire en une seule boucle.

Était-ce utile?

La solution

Avez-vous envisagé d'utiliser OfType méthode d'extension? Elle enveloppe un dénombrable et filtre les éléments de sorte que seuls ceux du type spécifié sont retournés. Vous pouvez l'utiliser comme ceci:

list.AddRange(superList.OfType(Of SubClass)())

ou même:

list = superList.OfType(Of SubClass)().ToList()

Désolé si ma syntaxe est désactivée, il a été un moment que je l'ai utilisé VB.NET


Modifier Exemple, comme promis:

namespace Demo.ListFilter
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;

    class Program
    {
        private class SuperClass
        {
        }

        private class SubClassA :
            SuperClass
        {
        }

        private class SubClassB :
            SuperClass
        {
        }

        static void Main(string[] args)
        {
            var superList = new List<SuperClass>()
            {
                new SuperClass(),
                new SuperClass(),
                new SuperClass(),
                new SuperClass(),
                new SubClassA(),
                new SubClassA(),
                new SubClassA(),
                new SubClassB(),
                new SubClassB(),
                new SubClassB(),
                new SubClassB()
            };

            var listA = new List<SubClassA>();
            var listB = new List<SubClassB>();

            SplitList(superList, listA, listB);

            Console.WriteLine("List A: {0}", listA.Count);
            Console.WriteLine("List B: {0}", listB.Count);
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        static void SplitList(IList superList, params IList[] subLists)
        {
            foreach(var subList in subLists)
            {
                var type = subList.GetType().GetGenericArguments()[0];
                FilterList(superList, subList, type);
            }
        }

        static void FilterList(IList superList, IList subList, Type type)
        {
            var ofTypeMethod = typeof(Enumerable).GetMethod("OfType");
            var genericMethod = ofTypeMethod.MakeGenericMethod(type);
            var enumerable = (IEnumerable)genericMethod.Invoke(null, new[] { superList });

            foreach(var item in enumerable)
            {
                subList.Add(item);
            }
        }
    }
}

Une autre édition: Vous pouvez également combiner les méthodes comme celle-ci:

    static void SplitList(IList superList, params IList[] subLists)
    {
        var ofTypeMethod = typeof(Enumerable).GetMethod("OfType");

        foreach(var subList in subLists)
        {
            var subListType = subList.GetType();
            var type = subListType.GetGenericArguments()[0];
            var genericOfTypeMethod = ofTypeMethod.MakeGenericMethod(type);
            var enumerable = genericOfTypeMethod.Invoke(null, new[] { superList });

            var addRangeMethod = subListType.GetMethod("AddRange");
            addRangeMethod.Invoke(subList, new[] { enumerable });
        }
    }

Ne pas oublier d'ajouter la gestion des erreurs!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top