在c#构造函数初始化中使用默认属性值
本文关键字:默认 属性 构造函数 初始化 | 更新日期: 2023-09-27 18:05:54
考虑以下类:
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;
你可以通过使用空合并运算符来简化它:
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中被忽略。
最简单和最易读的解决方案是:
var foo = new Foo();
if (bar != null)
foo.Bar = bar;
没有办法像你在初始化器中建议的那样进行验证(至少在c# 6中没有)。你可以使用一些结构来提取你的默认值为常量,就像这里的其他答案所建议的那样,但这会降低可读性,并且不会使使用类更容易-你必须了解实现(常量中的默认值)细节,这会破坏封装。
如果你主要关心的是代码风格,我建议你习惯if
s,因为它们没有什么问题,而且对于维护你的代码的其他人或你自己来说,它们很容易理解。
如果你还需要其他的东西,比如属性值的验证,你需要把它放在setter本身中(你应该在问题中说明)。
最干净的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; }
}
如果您将Bar
属性的默认值提取到static
字段:
public class Foo
{
public string Bar { get; set; } = defaultBarValue;
public static string defaultBarValue = "foobar";
}
你可以这样做:
new Foo
{
Bar = bar != null ? bar : Foo.defaultBarValue,
};
你可以做:
class Foo
{
public const string BarDefault = "foobar";
public string Bar { get; set; } = BarDefault;
}
var foo = new Foo { Bar = bar ?? Foo.BarDefault };
它的优点是在类的顶部拥有所有const中的默认值,但我个人并不认为这有什么意义。然而,这并不意味着你不需要条件语句。