考虑以下课程:
class Foo
{
public string Bar { get; set; } = "foobar";
}
这段代码:
var foo = new Foo {
Bar = bar == null
? null
: bar
};
显然,执行此代码后Bar
的值为null
(假设为bar = null
)。
我希望构造函数初始值设定项在给定的情况下使用默认属性值(例如,当bar
为null
时)。我想知道是否有更简单的方法来执行此操作而不是使用:
if (bar == null) {
foo = new Foo();
} else {
foo = new Foo { Bar = bar };
}
或者
foo = new Foo();
if (bar != null)
foo.Bar = bar;
答案 0 :(得分:2)
好吧,您可以使用null合并运算符来简化它:
var foo = new Foo();
foo.Bar = bar ?? foo.Bar;
或者您可以更改属性以检查空值并忽略它们:
private string _bar = "foobar";
public string Bar
{
get { return _bar; }
set { _bar = value ?? _bar; }
}
然后您可以使用此代码实例化Foo
:
var foo = new Foo() { Bar = bar };
注意,现在如果bar
为null,则在属性的setter中将忽略其值。
答案 1 :(得分:1)
最简单,最易读(IMHO)的解决方案是:
var foo = new Foo();
if (bar != null)
foo.Bar = bar;
无法像初始化程序中建议的那样进行验证(至少不是C#6)。你可以使用一些结构,将你的默认值提取为常量,就像这里建议的其他答案一样,但是这会带来可读性并且不会使类更容易使用 - 你必须知道实现(常量中的默认值)细节,这打破了封装。
如果您主要关注的是代码风格,我建议您习惯if
,因为它们没有任何问题,并且很容易理解其他人在几个月内维护您的代码或您自己。
如果你需要其他东西,比如属性值的验证,你需要将它放在setter中(你应该在问题中说明这一点)。
答案 2 :(得分:1)
最干净的OO方式是使用重载构造函数和工厂方法:
class Foo
{
public Foo Create(string bar)
{
return bar == null ? new Foo() : new Foo(bar);
}
public Foo() : this("foobar")
{
}
public Foo(string bar)
{
Bar = bar;
}
public string Bar { get; }
}
答案 3 :(得分:0)
你可以做:
class Foo
{
public const string BarDefault = "foobar";
public string Bar { get; set; } = BarDefault;
}
var foo = new Foo { Bar = bar ?? Foo.BarDefault };
它的优点是让所有默认值都在课堂顶部,但我个人并不真正看到这一点。但这确实意味着你不需要条件语句(种类)。
答案 4 :(得分:0)
如果您要将Bar
属性的默认值提取到static
字段:
public class Foo
{
public string Bar { get; set; } = defaultBarValue;
public static string defaultBarValue = "foobar";
}
你能够做到这一点:
new Foo
{
Bar = bar != null ? bar : Foo.defaultBarValue,
};
但我怀疑它值得努力...