创建简单的数据对象时,我经常遇到这种情况。我有一个名为Label的属性,它应该具有基于对象名称的默认值。因此,如果未设置标签,则使用名称,否则使用set Label。 C#中的一个简单例子
public class FooBat {
public string Name { get; set; }
public string Label {
get {
if (_label == null) return Name;
return _label;
}
set { _label = value; }
}
}
现在的问题是,如果你想编辑这个对象,你不能只是绑定到Label属性,或者你将得到默认值,它看起来好像有一个值,当真的没有。所以我最终做的是创建另一个只读属性来执行默认操作,我使用的是除了编辑基础对象之外的所有实例。这导致许多额外的属性与奇怪的名称,如LabelWithDefault。我尝试的另一个替代方法是使Label处理默认值并创建一个名为RealLabel的新属性,用于编辑基础对象。这同样糟糕。
我已经考虑过在其他地方移动默认代码,但我没有在任何“普通”模型中找到一个好地方,它不会多次复制默认代码。
我现在开始做的是在设置Name字段时初始化Label字段(并且Label字段不是),然后将Label字段视为普通字段。这有效,但现在默认代码与错误的属性相关联。为什么Name知道Label字段关心它?所以这也不是“正确的”。
有没有人有更好的方法来处理这个问题?
我认为我要求的内容有点混乱。基本上,对于两种不同的用途,我需要对同一对象有两种不同的视图。第一个是编辑对象本身,我希望未设置的字段显示为空(未设置)。第二个是针对所有其他情况(包括当对象是另一个对象的字段的值时),其中我想用动态确定的默认值显示每个字段。只是第一次设置默认值并没有帮助,因为如果(在这种情况下)名称字段发生更改,那么Label字段也必须更改,直到设置了Label字段。
答案越来越接近,但我仍然认为它们过于针对我给出的例子。我试图为说明目的提供一个具体的例子,但实际上这更像是一个最佳实践问题。我给出的例子是C#和字符串属性,但是我遇到的问题与我使用的大多数语言和系统有相同的框架,其中为您处理数据访问和数据显示以及除字符串以外的数据类型。更改从数据源查询的对象是可能的,但通常很棘手并且知道何时进行更改(在这种情况下使用子类而不是在那个中使用子类)特别困难。
答案 0 :(得分:1)
public class FooBat {
public string Name { get; set; }
public string Label {
get {
if (_label == null)
_label = Name;
return _label;
}
set { _label = value; }
}
}
关于您的更新: 您可以继承您的对象。如果尚未设置字段并且子类将返回默认值,则基类将返回null。因此,如果您需要查询是否已设置了值,则应转换为基类。
答案 1 :(得分:0)
为简洁起见删除了之前的答案/更新。
<小时/> 更新2: 我不得不说最好的方法是使用IsPropertySet bool跟踪属性是否已设置。属性的Getter将检查该值以查看它是否应返回其自己的值或默认值。并且属性的setter将根据设置值设置IsPropertySet(如果值不为null,则为true,否则为false)。然后,使用该类的代码可以查看IsPropertySet值以确定它是否正在接收设置值,或者在调用Property的Getter时是否为默认值。
public class FooBat {
public string Name { get; set; }
public bool IsLabelSet { get; set; }
public string Label {
get {
if (IsLabelSet)
return _label;
else
return Name;
}
set {
IsLabelSet = value != null;
_label = value;
}
}
}
答案 2 :(得分:0)
我经常使用Nameable
接口(getName()
)。在我开始之前,我建议你根本不想这样做。它应该是显示逻辑的域,而不是域对象。通常,消耗FooBat
的代码能够以比对象本身更好的方式做出此决策。除此之外......
public interface Label{
string getLabel();
boolean isDefault(); //or isValued() or use instanceof expressions
}
public interface Nameable{
string getName();
}
public class FooBat implements Nameable {
public string Name { get; set; }
public Label Label {
get {
if (_label == null) {
_label = new DefaultLabel(this);
}
return _label;
}
set { _label = value; }
}
}
public class DefaultLabel implements Label{
public DefaultCharSequence(Nameable named){
this.named = named;
}
public string getLabel(){
return named.getName();
}
public boolean isDefault(){ return true; }
}
public class StringLabel implements Label {
...
}
这一切基本归结为为标签对象返回更好的类。