只读字段作为子类构造函数的目标

发布于 2024-12-09 05:12:36 字数 360 浏览 1 评论 0原文

当您有一个在对象实例化时已知的变量且此后不应更改时,应使用只读字段。

然而,不允许从子类的构造函数中分配只读字段。 如果超类是抽象的,这甚至不起作用。

有谁有一个很好的解释为什么这不是一个好主意,或者缺乏 C# 语言?

abstract class Super
{
    protected readonly int Field;
}

class Sub : Super 
{
    public Sub()
    {
        this.Field = 5; //Not compileable
    }
}

PS:当然,您可以通过在超类的受保护构造函数中分配只读字段来达到相同的结果。

A readonly field should be used when you have a variable that will be known at object-instatiation which should not be changed afterwards.

However one is not allowed to assign readonly fields from constructors of subclasses.
This doesn't even work if the superclass is abstract.

Does anyone have a good explanation why this either isn't a good idea, or lacks in the C# languange?

abstract class Super
{
    protected readonly int Field;
}

class Sub : Super 
{
    public Sub()
    {
        this.Field = 5; //Not compileable
    }
}

PS: You can of course reach the same result by having assignment of the readonly fields in a protected constructor in the superclass.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

别再吹冷风 2024-12-16 05:12:36

我能看到这一点的唯一原因是因为“它就是这样设计的”,根据 规范

对只读字段的直接赋值只能作为其中的一部分发生
声明或在实例构造函数或静态构造函数中
同一个班级。

只读的要点是它不能更改,如果派生类可以修改,那么这将不再成立,并且将违反封装(通过修改另一个类的内部)。

The only reason I can see for this is because "it was just designed that way", as per the spec:

Direct assignments to readonly fields can only occur as part of that
declaration or in an instance constructor or static constructor in the
same class.

The point of being read only is that it cannot be changed, if derived classes could modify then this would no longer be true and will violate encapsulation (by modifying the internals of another class).

习惯成性 2024-12-16 05:12:36
public class Father
{
    protected readonly Int32 field;

    protected Father (Int32 field)
    {
        this.field = field;
    }
}

public class Son : Father
{
    public Son() : base(5)
    {

    }
}

你可以尝试这样的事情!

public class Father
{
    protected readonly Int32 field;

    protected Father (Int32 field)
    {
        this.field = field;
    }
}

public class Son : Father
{
    public Son() : base(5)
    {

    }
}

You may try something like this instead!

轻拂→两袖风尘 2024-12-16 05:12:36

我将通过 C# 中的抽象/虚拟属性对此进行建模。

abstract class Super {
  protected abstract int Field { get; }
}

class Sub : Super {
  protected override int Field { get { return 5; } }
}

在我看来,这是一个比使用包含每个只读字段作为参数的构造函数更好的解决方案。一方面是因为编译器也能够内联它,另一方面因为构造函数解决方案在派生类中将如下所示:

class Sub : Super {
  public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}

此外,如果您已经有一个采用单个 int 值的构造函数,那么这可能不起作用。

I would model this by an abstract/virtual property in C#.

abstract class Super {
  protected abstract int Field { get; }
}

class Sub : Super {
  protected override int Field { get { return 5; } }
}

In my opinion that's a better solution than to have a constructor that includes each and every readonly field as parameter. For one because the compiler is able to inline this as well and also because the constructor solution will look like this in the derived class:

class Sub : Super {
  public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}

Also that may not work if you already have a constructor that takes a single int value.

弄潮 2024-12-16 05:12:36

我认为主要原因是所有 .NET 语言实现

都增加了复杂性,总有一个简单的解决方法:

 abstract class Super
 {
     protected readonly int Field;

     protected Super(int field)
     {
          this.Field = field;
     }
 }


class Sub : Super {
   public Sub():base(5)
   {
   }

}

I suppose the main reason is an additional complexity for all .NET language implementations

also, there is always a simple workaround:

 abstract class Super
 {
     protected readonly int Field;

     protected Super(int field)
     {
          this.Field = field;
     }
 }


class Sub : Super {
   public Sub():base(5)
   {
   }

}

無心 2024-12-16 05:12:36

我更喜欢在超类中使用受保护的构造函数(如 alexm 提到的),并带有 xml 注释。
这应该可以消除 DonAndre 在代码注释中所说的问题。

I would prefer to use the protected constructor in superclass (as mentioned by alexm), reachly with xml comments.
This should eliminate the problem what DonAndre told in his code comment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文