【问题标题】:How to fix constructor loop in derived class?如何修复派生类中的构造函数循环?
【发布时间】:2019-10-28 03:03:58
【问题描述】:

我不希望派生类(Ecri1 和 Ecri2)在 CCEAG 以外的其他地方被知道,但是当我这样尝试时,我得到了 StackOverflowException,因为会调用一个构造函数循环。

    class Program
    {
        static void Main(string[] args)
        {
            CCEAG state = new CCEAG();
        }
    }

    public class CCEAG 
    {
        public CCEAG MachineSpecificState;

        public MachinesEnum CurrentMachine { get; set; }

        public enum MachinesEnum
        {
            ECRI1,
            ECRI2,
        }
        public CCEAG()
        {
            if (MachineSpecificState == null)
            {
                switch (CurrentMachine)
                {
                    case MachinesEnum.ECRI1:
                        MachineSpecificState = new Ecri1();
                        break;
                    case MachinesEnum.ECRI2:
                        MachineSpecificState = new Ecri2();
                        break;
                    default:
                        CurrentMachine = MachinesEnum.ECRI1;
                        MachineSpecificState = new Ecri1();
                        break;
                }
            }
        }

    }

    public class Ecri1 : CCEAG
    {
    }

    public class Ecri2 : CCEAG
    {
    }

解决此问题的最佳做法是什么?我是否需要放弃 CCEAG 并将其所有代码复制到 Ecri1 和 Ecri2 并让 Program 知道它们?

【问题讨论】:

  • 请显示所有相关代码。例如,您正在执行此假定循环行为的实例化的代码。
  • 另外,请查看 .net 的命名约定。类应该用大写字母命名,而不是全部大写,并且名称应该具有足够的描述性,以便您了解类的用途。
  • CCEAG的构造函数被调用时,MachineSpecificState永远为null,CurrentMachine永远为ECRI1。如果完全设置了它们,那么直到调用构造函数之后才会设置。
  • @rory.ap 这是一个最小的例子。如果你运行它,你会看到我描述的循环行为。我已经缩短了这个问题的类名。
  • 确保MachineSpecificState 得到一个值,在你的示例代码中它总是null,因此你的问题。

标签: c# stack-overflow derived-class


【解决方案1】:

您需要从类CCEAG 的构造函数中放弃构造类CCEAG,这会导致您正在观察的无限递归。

如果您想“隐藏”类,请将它们设为私有并创建工厂公共静态函数,这些函数会创建所述类的实例。

class CCEAG {
    private class Ecri1 : CCEAG { };
    static public CCEAG createEcri1() { return new Ecri1(); }
};

【讨论】:

  • 投了赞成票,但我相信你有一个 type-o,我不能自己编辑,因为它涉及的字符少于 6 个。
  • 在哪里?是的,这个限制很烦人。
  • 'public' 后面的冒号和新行。除非我误解了你在做什么。
  • 已修复。谢谢。
【解决方案2】:

看起来您假设的是静态 Machine* 数据(在 CCEAG 实例之间共享)

    public static CCEAG MachineSpecificState;

    public static MachinesEnum CurrentMachine { get; set; }

如果可能的话,将它们更改为 private 而不是 public

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2016-07-19
    • 1970-01-01
    相关资源
    最近更新 更多