0

所以我有这门课

public class Options
    {
        public bool show { get; set; }
        public int lineWidth { get; set; }
        public bool fill { get; set; }
        public Color fillColour { get; set; }
        public string options { get; set; }

        public virtual void createOptions()
        {
            options += "show: " + show.ToString().ToLower();
            options += ", lineWidth: " + lineWidth;
            options += ", fill: " + fill.ToString().ToLower();
            options += ", fillColor: " + (fillColour != Color.Empty ? ColourToHex(fillColour) : "null");
        }

        public Options(bool _show, int _lineWidth, bool _fill, Color _fillColour)
        {
            show = _show;
            lineWidth = _lineWidth;
            fill = _fill;
            fillColour = _fillColour;

            createOptions();
        }
}

和另一个继承它的类

public class Line : Options
    {
        public static bool steps { get; set; }

        public override void createOptions()
        {
            options += ", lines: {";
            options += " steps: " + steps.ToString().ToLower() + ",";
            base.createOptions();
            options += "}";
        }

        public Line(bool _show, int _lineWidth, bool _fill, Color _fillColour, bool _steps)
            : base(_show, _lineWidth, _fill, _fillColour) { steps = _steps; }
    }

调用对象Line(true, 1, true, Color.Gray, true)时,它首先覆盖继承的类函数,然后设置stepstrue.

我想steps被包含在覆盖中,所以steps现在将true代替false(它的默认值)。

如果可能的话,请给我一些关于如何解决这个问题的指示和提示,并向我解释为什么我的设置不允许在构造函数初始化之后发生覆盖。

4

3 回答 3

0

我想你忘了向我们展示Options类构造函数,但我猜它调用了createOptions()方法。

在 C# 中,您不能在任何地方调用基本构造函数。基本构造函数总是在给定构造函数启动之前调用。你可以参考这个 url 来了解更多关于构造函数链的信息:

http://www.yoda.arachsys.com/csharp/constructors.html

但是你可以通过稍微改变你的架构来得到你想要的。正如我所看到的,您的options属性是ToString()Options 类的一个。您不需要在构造函数时准备好此属性。

一些选项:

  1. 在 options get 访问器中将 Options 类转换为字符串。
  2. 消除 options 属性,而是实现一个 toString 方法,该方法将调用 createOptions 或只是它的内容
于 2009-11-20T02:50:26.697 回答
0

我在代码中没有看到Options类的构造函数,但我猜测它首先将给定的四个参数复制到对应的字段中,然后调用createOptions来初始化options字段。这实际上是一个很好的例子,说明了为什么在构造函数中调用虚方法是不好的做法。在基类的构造函数完成之前,无法设置派生类的任何字段,因此被覆盖的方法将使用 steps 字段的默认值。

有很多方法可以解决这个问题,但你应该做的第一件事是避免在构造函数中调用虚方法。我这样做的方法是将 options 属性设为只读并将其 getter 设为虚拟,以便在需要时计算该值。

编辑。我没有注意到步骤是静态的。那我不明白你为什么要在实例构造函数中设置它。

于 2009-11-20T02:53:14.803 回答
0

因此,在使用静态类成员时,这里有一些技巧,例如public static bool steps

  1. 第一次加载类时,静态成员被初始化为其默认值(在这种情况下为 false)。请记住,静态成员属于类而不是实例,因此它们不能被覆盖,但可以使用new关键字隐藏在派生类中。

  2. 您可以使用称为静态构造函数的特殊构造函数来显式初始化静态类成员......因此您不应该尝试在实例构造函数中初始化它们,就像您的代码片段所示。

对 C# 静态成员的快速 Google 搜索可能会有所帮助: Link to C# Help on Static Members

于 2009-11-20T02:54:09.390 回答