【问题标题】:Static readonly field cannot be assigned to (except in static constructor)不能分配静态只读字段(静态构造函数除外)
【发布时间】:2011-04-23 22:49:30
【问题描述】:
abstract class DirectiveNode
{
    public static readonly RequirementOptions ArgumentOptions = RequirementOptions.Optional;
}

class IfNode : DirectiveNode
{
    static IfNode()
    {
        ArgumentOptions = RequirementOptions.Required; // error here
    }

我不明白这个问题。我以为static IfNode() 是静态构造函数?为什么会出错?


刚刚发现:Assigning to static readonly field of base class

【问题讨论】:

    标签: c# debugging syntax


    【解决方案1】:

    只能在类的静态构造函数中赋值。

    顺便说一句,听起来您希望静态字段包含不同的值,具体取决于您所谈论的派生类。这不是它的工作方式。该字段仅存在一个实例,并且在所有派生类之间共享。

    【讨论】:

    • 是的....这就是我想要做的。那有什么解决办法呢?我真的不想让它成为非静态的......它应该被限制为每个类一个实例。
    • 您可以将基类设为泛型,泛型类型参数作为后代类,然后每个泛型类型参数的静态字段将存在一次。但是......您仍然无法将其设为只读并从基类分配给它。
    • @Lasse:嗯……这可能行得通,但听起来不太漂亮。
    • @Mark 我没说会,而且你仍然对只读部分有问题。我的建议是找到一种不同的方法。
    • @Lasse:像 dalhbyk 建议的那样?仍然比我想要的更冗长,但是哦,好吧。我认为这是我们能做的最好的了。
    【解决方案2】:

    与非静态构造函数不同,子类的静态构造函数与父静态构造函数没有关系。如果您希望子类能够更改基类函数使用的 ArgumentOptions 值,请考虑使用虚拟属性:

    abstract class DirectiveNode
    {
        public virtual RequirementOptions ArgumentOptions
        {
            get { return RequirementOptions.Optional; }
        }
    }
    
    class IfNode : DirectiveNode
    {
        public override RequirementOptions ArgumentOptions
        {
            get { return RequirementOptions.Required; }
        }
    }
    

    【讨论】:

    • 哦..这可能有用。 MS就是这样做事的,不是吗?我隐约记得SyncRoot 是这样实现的。
    • 是的,这种技术被大量使用。一个例子是System.Linq.Expressions.Expression.Type,被不同类型的表达式覆盖。
    • 如果值需要一些计算,并且不返回简单的枚举怎么办?我不想每次获取它时都重新计算它...nvm...您只需添加一个私有成员,存储它,然后从那里检索它。
    • 没错。如果您愿意,该私有成员可以是静态的并在所有 IfNode 实例之间共享,如果没有 virtual,它就无法共享到基类。
    猜你喜欢
    • 2015-06-28
    • 2011-02-15
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 2014-09-16
    • 1970-01-01
    相关资源
    最近更新 更多