3

私にはいくつかのクラスがあり、それらはすべてSuperClassから派生しています。

クラスが作成されると、それらはすべてList(Of SuperClass)に入れられます。リストを確認するとき、SuperClassオブジェクトをそのbaseObjectにダウンキャストして、正しいリストに入れたいと思います。(SuperClassのサブタイプごとに1つのリストを作成しました)。

以下を決定することが可能です:

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

しかし、いくつかのクラスがある場合、これは多くの作業です。

を使用して

SuperClass.GetType.FullName

サブクラスのタイプを取得します。

私の質問は、これを使用してSuperClassオブジェクトを動的にキャストすることは可能ですか?擬似コード:

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

編集:サブクラスごとに1つのケースを作成する代わりに変数を使用して、すべてを1つのループで実行できることを望んでいました。

4

1 に答える 1

4

LINQのOfType拡張メソッドの使用を検討しましたか?列挙可能な要素をラップし、指定されたタイプの要素のみが返されるように要素をフィルタリングします。あなたはそれをこのように使うことができます:

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

あるいは:

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

構文がオフの場合は申し訳ありませんが、VB.NETを使用してからしばらく経ちました


編集:約束通りの例:

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

別の編集:次のような方法を組み合わせることもできます。

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

エラー処理を追加することを忘れないでください!

于 2010-02-26T07:31:30.250 に答える