【问题标题】:Setting Default Value to a property on c# [duplicate]在c#上将默认值设置为属性[重复]
【发布时间】:2012-10-14 18:41:33
【问题描述】:

可能重复:
Setting the default value of a DateTime Property to DateTime.Now inside the System.ComponentModel Default Value Attrbute

我正在创建一个类似于日历的控件,并且我希望用户设置他们想要查看的年份。 但如果不是,则 SelectedYear 的属性必须是实际年份。

我尝试像这样设置这个默认值:

[DefaultValue(DateTime.Today.Year)]
public int SelectedYear{
    get{
        return _selYear;
    }
    set{
        _selYear = value;
        UpdateCalendar();
    }
}

我收到以下错误

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

【问题讨论】:

  • 这不是该属性的用途。在类的默认 ctor 中设置默认属性值是一种常见的选择。
  • 这是设计器默认值,意味着如果控件具有给定的年份值,则该值在属性窗口中不会加粗。它不会影响属性值。
  • 如果您正在构建一个控件,那么我相信在构造函数中设置默认值将是一个好地方。
  • 您应该使用AmbientValueAttribute 类来定义一个值,当设置为属性时,该值实际上表示当前日期...看看我的答案。此外,这为设计者提供了有关控件如何工作的线索。

标签: c#


【解决方案1】:

DateTimeYear 属性是一个计算值,但您试图将其嵌入到一个属性中,该属性是存储在二进制文件中的不可变值。这两个概念不兼容。

您在这里要做的是有一个标记来说明该值尚未设置,并在这种情况下返回当前的Year。这是使用可空对象的好地方

int? _selYear;
public int SelectedYear {
  get { return _selYear ?? DateTime.Today.Year; }
  set { 
    _selYear = value;
    UpdateCalendar();
  }
}

【讨论】:

    【解决方案2】:

    AmbientValueAttribute表示,当你把属性设置为默认值时,其实就是获取当前日期的意思。

    int _selYear = 0;
    
    [AmbientValue(0)]
    [DefaultValue(0)]
    public int SelectedYear{
        get{
            if (_selYear == 0)
                return DateTime.Today.Year;
            return _selYear;
        }
        set{
            _selYear = value;
            UpdateCalendar();
        }
    }
    

    如果你想使用0值,那么你可以让它为空,但永远不返回null,只允许设置null:

    int _selYear = null;
    
    [AmbientValue(null)]
    [DefaultValue(null)]
    public int? SelectedYear{
        get{
            return _selYear ?? DateTime.Today.Year;
        }
        set{
            _selYear = value;
            UpdateCalendar();
        }
    }
    

    现在,它是表示当前年份的空值。

    AmbientValueAttribute的意思是:如果你把这个属性设置成那个值,当你拿到这个属性的时候,会从环境中返回另一个值,那个情况下的返回值可能会有所不同,只是比如当前日期。

    【讨论】:

      【解决方案3】:

      您应该显式地初始化属性的值。 DefaultValue 属性不会通过值初始化属性,它只是提供默认值的元数据。

      您可以在类型的 ctor 中对其进行初始化,也可以编写自定义代码来反映类型并通过类型元数据中的值初始化属性。

      【讨论】:

        【解决方案4】:

        嗯,错误很明显:

        属性参数必须是常量表达式...

        那么,如果 确实 有效,那么默认值实际上是什么?嗯,这将是您编译代码的那一年。可能不是你想要的。

        如果您真的想默认返回当前年份,那么只需在构造函数中将其初始化为该年份即可。

        【讨论】:

          【解决方案5】:

          为什么不 set backing field 而不是像这样在构造函数中 -

          _selYear = DateTime.Today.Year
          

          如果用户没有设置它,它将始终是 default 值。

          【讨论】:

            【解决方案6】:

            DateTime.Today.Year 不是一个常数值,因为它每年都在变化。您可以使用以下命令检查是否指定了 _selYear

            public int SelectedYear{
                get{
                    if (_selYear.Equals(0)){
                        return  DateTime.Today.Year;
                    }
                    else{
                        return _selYear;
                    }
                }
                set{
                    _selYear = value;
                    UpdateCalendar();
                }
            }
            

            这是考虑到您将 _selYear 初始化为 0。

            【讨论】:

              【解决方案7】:

              这是因为DefaultValue 只接受常量值。您可以通过另一种方法来做到这一点,如下所示

              public int SelectedYear{
                  get{
                      return _selYear == 0 ? DateTime.Now.Year : _selYear;
                  }
                  set{
                      _selYear = value;
                      UpdateCalendar();
                  }
              }
              

              希望这会有所帮助!

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2010-10-16
                • 1970-01-01
                • 1970-01-01
                • 2012-04-07
                • 2011-03-21
                • 2017-02-16
                • 2023-03-15
                • 1970-01-01
                相关资源
                最近更新 更多