【问题标题】:Iterate through sub classes of a base class and instantiate them遍历基类的子类并实例化它们
【发布时间】:2017-02-08 18:52:26
【问题描述】:

我有一个基类,以及从它继承的大量子类。我希望创建一个包含这些子类实例中的每一个的列表。目前我必须做的:

List<BaseClass> bigList = new List<BaseClass>;

for (int i = 0; i < 3; i++){
   bigList.Add(new A());
   bigList.Add(new B());
   etc.

其中 A 和 B 是其中的两个子类。有什么方法可以遍历所有类而不必单独声明它们,如下所示:

foreach (Class classname in listOfClasses){
   for (int i = 0; i < classname.numberToAdd; i++){
      bigList.Add(new classname());
   }
}

“类名”实际上等同于 A、B、C 等。

这会有所帮助,因为实际程序更复杂,因为添加的数量取决于所讨论的类(我可能需要四个 A,五个 B,而不是 C 等)。

有没有更好的方法来完全做到这一点? 我是不是必须走很长的路?

【问题讨论】:

  • 我的意思是,你可以使用反射,但听起来你有更大的设计问题。
  • 您需要使用反射来查找您的类并实例化新对象。
  • @UladzimirPalekh 他没有提到他想要实例化。只返回一个名称列表。
  • 另一种解决方案是使用工厂模式,每个不同的子类都绑定到一个数字。
  • 这些都在同一个程序集中吗?

标签: c#


【解决方案1】:

使用反射查找程序集中的所有类型,并测试它们是否派生自您的基类。您可以使用自定义属性进行实例化计数:

class Program {
        static void Main(string[] args) {
            List<BaseClass> bigList = new List<BaseClass>();
            foreach (var type in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()) {
                if (typeof(BaseClass).IsAssignableFrom(type) && !(type.IsAbstract)) {
                    var ctor = type.GetConstructor(Type.EmptyTypes);
                    if (ctor != null) {
                        var countAttr = Attribute.GetCustomAttribute(type, typeof(InstantiationCountAttribute)) as InstantiationCountAttribute;
                        if (countAttr != null) {
                            for (int i = 0; i < countAttr.Count; ++i) {
                                bigList.Add((BaseClass)ctor.Invoke(null));
                            }
                        }
                    }
                }
            }
            foreach (var test in bigList) {
                Console.WriteLine(test.GetType().Name);
            }
        }        
    }
    abstract class BaseClass {
    }
    class InstantiationCountAttribute : Attribute {
        public InstantiationCountAttribute(int count) {
            Count = count;
        }
        public int Count { get; private set; }
    }

    [InstantiationCount(1)]
    class A : BaseClass {
    }

    [InstantiationCount(34)]
    class B : BaseClass {
    }

【讨论】:

  • 这看起来不错,谢谢。但是是否可以使用子类的属性而不是属性来存储实例化计数?
  • 是的。在基类中为计数创建一个抽象属性。然后,您将实例化第一个,查询计数,并确定要实例化和/或添加多少个。
猜你喜欢
  • 2018-08-17
  • 1970-01-01
  • 2012-06-11
  • 2012-08-20
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多