【问题标题】:Set default value on properties when null为空时设置属性的默认值
【发布时间】:2016-08-19 10:49:03
【问题描述】:

我正在尝试定义一种在 C# 中为我的属性设置默认值的方法。

我有很多元素 TextBox 和一个按钮来恢复默认值。我希望当用户单击按钮时,TextBox 的内容设置为默认值。

我的想法是将 value 设置为 null 并在 setter 中检查 value,如果 value 为 null,则设置默认值。

这是我的代码:

private void SetDefault()
{
    Grid actualItem = tabControl.SelectedContent as Grid;
    if (actualItem != null)
    {
        foreach (object elt in actualItem.Children)
        {
            if (elt.GetType() == typeof(TextBox))
            {
                TextBox box = elt as TextBox;
                box.Text = null;
            }
        }
    }
}

文本框示例:

<TextBox Grid.Row="1" Grid.Column="1"
         Style="{StaticResource TextBoxStyle}"
         Text="{Binding ExamplePropertie,
                Mode=TwoWay,
                UpdateSourceTrigger=PropertyChanged}"/>

对于每个绑定的元素,我想做这样的事情:

[DefaultValue("default")]
public String ExamplePropertie
{
    get
    {
        return _myProp;
    }
    set
    {
        if (value == null)
            default(ExamplePropertie); // Not working
        else
            _myProp = value;
        OnPropertyChanged(nameof(ExamplePropertie));
    }
}

但是default(ExamplePropertie) 不是这样做的好方法。如何设置使用[DefaultValue(value)] 定义的值?

【问题讨论】:

  • 你应该在你的属性旁边引入一个const 值,并在属性和设置器中的代码中使用它。
  • 您的代码没有使用绑定,而是直接将值分配给文本框。数据绑定意味着您告诉控件在哪里可以找到数据。您正在构建什么样的应用程序?例如,在 WPF 中,您可以在绑定表达式中指定默认值
  • 代码default(ExamplePropertie) 只是获取type 的默认值,对于任何引用类型始终为nullDefaultValue 属性与此无关。
  • @LasseV.Karlsen 所以我必须通过属性编写一个常量?@PanagiotisKanavos 我添加了绑定部分,它在 WPF 的视图中。我会看看你的解决方案。

标签: c# default-value


【解决方案1】:

好吧,您可以借助反射来获取该属性的值,但更简单的方法是将默认值存储为 const:

private const string ExamplePropertieDefault = "default";

[DefaultValue(ExamplePropertieDefault)]
public String ExamplePropertie
{
    get
    {
        return _myProp;
    }
    set
    {
        if (value == null)
            ExamplePropertieDefault;
        else
            _myProp = value;
        OnPropertyChanged(nameof(ExamplePropertie));
    }
}

【讨论】:

  • 那样的话,[DefaultValue()] 是没用的,不是吗?
  • 为什么这么说?你知道 DefaultValueAttribute 是做什么的吗?它被诸如序列化程序之类的东西用来通过省略具有默认值的属性来优化输出。序列化程序知道可以安全省略的方式是该属性具有与 DefaultValueAttribute 中指定的值相同的值。所以不,它不是没用的。在您的情况下可能没有必要,但只有您自己知道。
  • 好吧,我不知道这一切。到时我会保留它。谢谢你的解释。
【解决方案2】:

[DefaultValue(...)] 是一个属性。您无法通过将default(...) 应用于您的财产名称来获得其价值。这个过程更复杂:你需要为你的属性获取PropertyInfo 对象,查询它以获取DefaultValueAttribute 类型的自定义属性,然后才能从中获取值。

使用辅助方法可以更轻松地完成此过程:

static T GetDefaultValue<T>(object obj, string propertyName) {
    if (obj == null) return default(T);
    var prop = obj.GetType().GetProperty(propertyName);
    if (prop == null) return default(T);
    var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
    if (attr.Length != 1) return default(T);
    return (T)((DefaultValueAttribute)attr[0]).Value;
}

把这个辅助方法放到一个单独的类中,如下使用:

_myProp = value ?? Helper.GetDefaultValue<string>(this, nameof(ExampleProperty));

注意: SetDefault 中的foreach 循环可以这样简化:

foreach (object box in actualItem.Children.OfType<TextBox>()) {
    box.Text = null;
}

【讨论】:

  • obj.GetProperty(propertyName) 不能编译,但使用obj.GetType().GetProperty(propertyName) 效果很好!我不知道OfType 谢谢你的提示!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多