简体   繁体   English

c#继承类初始化

[英]c# inherited class initialization

so with this class i have所以这门课我有

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

and another class that inherits it和另一个继承它的类

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

When calling the object Line(true, 1, true, Color.Gray, true) it does the override of the inherited class function first, then sets steps to true .当调用对象Line(true, 1, true, Color.Gray, true)它首先覆盖继承的类函数,然后将steps设置为true

I want steps to be included in the override so steps will now be true instead of false (its default).我希望将steps包含在覆盖中,因此现在steps将为true而不是false (其默认值)。

If its possible please gimme some pointers and tips on how to fix this and explain to me why my setup will not allow for the override to happen after the constructor init.如果可能,请给我一些有关如何解决此问题的指示和提示,并向我解释为什么我的设置不允许在构造函数初始化之后发生覆盖。

I suppose you forgot to show us the Options class constructor, but I guess it calls the createOptions() method.我想你忘了向我们展示Options类的构造函数,但我猜它调用了createOptions()方法。

In C# you just can't call a base constructor wherever you want.在 C# 中,您无法在任何地方调用基本构造函数。 The base constructor is always called before the given constructor starts.基构造函数总是在给定的构造函数开始之前被调用。 You may refer to this url to know more about constructor chaining:你可以参考这个 url 来了解更多关于构造函数链的信息:

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

But you can get what you want by changing your architecture a little.但是你可以通过稍微改变你的架构来得到你想要的。 As I see this, your options property is a ToString() of the Options class.正如我所看到的,您的options属性是 Options 类的ToString() You do not need this property to be ready at constructor time.您不需要在构造函数时准备好此属性。

Some options:一些选项:

  1. Convert the Options class to string in the options get accessor.在选项获取访问器中将选项类转换为字符串。
  2. Eliminate the options property and, instead, implement a toString method that would call createOptions or just it's content消除 options 属性,而是实现一个 toString 方法,该方法将调用 createOptions 或仅调用它的内容

I don't see the constructor of the Options class in the code, but I guess that it first copies the four given parameters to the corresponding fields and then calls createOptions to initialize the options field.代码中没有看到Options类的构造函数,但是我猜是先把给定的四个参数复制到对应的字段中,然后调用createOptions来初始化options字段。 This is actually a very good example of why it's bad practice to call virtual methods in constructor.这实际上是一个很好的例子,说明为什么在构造函数中调用虚方法是不好的做法。 There is no way to set any field of the derived class until the base class's constructor is done, so the overridden method will use the default value of the steps field.在基类的构造函数完成之前,无法设置派生类的任何字段,因此重写的方法将使用步骤字段的默认值。

There are many ways you can fix this, but the first thing you should do is avoid calling virtual methods in constructor.有很多方法可以解决这个问题,但你应该做的第一件事是避免在构造函数中调用虚方法。 The way I would do this is make options property read-only and make its getter virtual, so that it calculates the value when it's needed.我这样做的方法是将 options 属性设为只读并将其 getter 设为虚拟,以便在需要时计算该值。

Edit.编辑。 I didn't notice that steps is static.我没有注意到步骤是静态的。 Then I don't understand why do you set it in instance constructor.然后我不明白你为什么要在实例构造函数中设置它。

So here are some tips when working with static class members like public static bool steps :因此,这里有一些使用静态类成员(如public static bool steps

  1. Static members are initialized to their default values (false in this case) when the class is loaded for the first time.第一次加载类时,静态成员被初始化为其默认值(在本例中为 false)。 Remember that static members belong to the class and not the instance so they cannot be overridden, but can be hidden in derived classes by using the new keyword.请记住,静态成员属于类而不是实例,因此它们不能被覆盖,但可以使用new关键字隐藏在派生类中。

  2. You can use a special constructor called a static constructor to explicitly initialize static class members... so you shouldn't try to initialize them in an instance constructor like your code snippet illustrates.您可以使用称为静态构造函数的特殊构造函数来显式初始化静态类成员......所以您不应该尝试像您的代码片段所示那样在实例构造函数中初始化它们。

A quick Google search on C# static members might be helpful: Link to C# Help on Static Members在 Google 上快速搜索 C# 静态成员可能会有所帮助: Link to C# Help on Static Members

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM