【问题标题】:Create a compile error instead of run time error创建编译错误而不是运行时错误
【发布时间】:2012-10-29 10:15:07
【问题描述】:

我的代码需要设置我的类的一个字段,但我希望该字段只设置一​​次。如果开发人员尝试重置/更改它,理想情况下我希望编译器告诉我们关闭而不是出现运行时错误。这可能吗?

帮助解释的代码

internal class Message
    {
        private string title = string.Empty;

        public string Title
        {
            get { return title; }
            set 
            {
                if (string.IsNullOrEmpty(title))
                    title = value;
                else
                    throw new Exception("Title can only be set once!");
            }
        }
    }

如您所见,上面会抛出异常,但这是运行时错误。尽管此处的示例相当简单,但编写编译器错误或警告消息的概念可能非常有益。

【问题讨论】:

  • readonly不够用怎么办?
  • 程序无法编译;如果我创建“私有只读字符串标题”或“公共只读字符串标题”,我会收到错误消息“修饰符 'readonly' 对此项目无效'
  • 那么显然有一些错误。请发布不起作用的代码。
  • 就是代码!如果我将'private readonly string title = string.Empty'设为私有(或者如果我将其更改为'private readonly string title;')我会收到消息:“修饰符'readonly'对此项目无效”。如果我将公共字符串标题设为只读(公共只读字符串标题),则消息为“无法将只读字段分配给(在构造函数或变量初始化程序中除外)”
  • 查看这里的想法和背景:stackoverflow.com/questions/6266031/…

标签: c# compiler-errors runtime-error


【解决方案1】:

您要求的是自定义编译器规则,AFAIK 是不可能的。 IMO你有2个选项,一个是让它成为构造函数的一部分,所以它只能设置一次,例如

internal class Message
{
    public Message(string title)
    {
        Title = title;
    }

    public string Title { get; private set; }
}

另一个是保持它的方式,但是,抛出一个更合适的异常,例如

internal class Message
{
    private string title = string.Empty;

    public string Title
    {
        get { return title; }
        set 
        {
            if (string.IsNullOrEmpty(title))
                title = value;
            else
                throw new InvalidOperationException("Title can be set only once!");
        }
    }
}

不管怎样,Title 属性只会被设置一次。

【讨论】:

  • 但是这些中的任何一个都会通过编译警告消息提醒开发人员吗?
  • @Dave 第一个会 - 它现在不可写,必须通过构造函数设置
  • @MarcGravell 谢谢你-谢谢詹姆斯的编辑,这已经回答了它:)
  • 对于信息,我认为这里的第二种方法并不理想......默默地拒绝更改属性不是一个好的结果(并且不会按照问题的要求做);不过,第一种方法的 +1 非常强
  • 是的,我同意(因此为什么原始代码在尝试时会抛出错误)
【解决方案2】:

只需使用readonly 字段:

private readonly string title;

public Message(string title) { this.title = title; }

编译器will emit an error 如果该字段是从其他任何地方分配给的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    相关资源
    最近更新 更多