在构造期间设置成员的 C# 惯用方法是什么?
What's the C#-idiomatic way to set a member during construction?
我发现自己写了很多看起来像这样的代码:
new Foo(7, "a");
其中 Foo
看起来像:
class Foo {
int bar;
string baz;
public Foo(int bar, string baz) {
this.bar = bar;
this.baz = baz;
}
}
受过 C# 培训的程序员将如何处理此问题?写 this.bar = bar
和 this.baz = baz
可以,但感觉很奇怪。
您可以使用对象初始化语法:
var foo = new Foo() { bar = 7, baz = "a" };
它要求您的字段为 public 并且属性具有 setter。
编译器会将其翻译成如下代码:
var temp = new Foo();
temp.bar = 7;
temp.baz = "1";
var foo = temp;
我会使用属性而不是字段 - 如果您需要向属性添加逻辑,将来修改起来会更容易。
class Foo
{
public int Bar { get; private set; }
public string Baz { get; private set; }
public Foo()
{
}
public Foo(int bar, string baz)
{
Bar = bar;
Baz = baz;
}
}
一个流行的约定是在私有字段名称前加上_
前缀,以区别于普通参数名称,例如
class Foo {
int _bar;
string _baz;
public Foo(int bar, string baz) {
_bar = bar;
_baz = baz;
}
}
那么就不需要使用 this
了。或者,由于您在问题标题中提到了 properties,您可以将这些字段封装在属性中并进行设置:
class Foo {
int _bar;
string _baz;
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar
{
get { return _bar; }
set { _bar = value; }
}
public string Baz
{
get { return _baz; }
set { _baz = value; }
}
}
由于 C# 有 case-sensitive 个符号名称,this
仍然是不必要的。现在,如果您没有对属性的 get/set 行为做任何比这更复杂的事情,您可以使用 auto-property 语法 :
class Foo {
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar { get; set; }
public string Baz { get; set; }
}
现在,如果您的共同需求是这些属性可以从外部读取 class 但只能从内部设置,您可以将它们设置为只读:
class Foo {
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar { get; private set; }
public string Baz { get; private set; }
}
但是如果您希望它们真正只在构造函数中设置,您可以返回使用字段:
class Foo {
readonly int _bar;
readonly string _baz;
public Foo(int bar, string baz) {
_bar = bar;
_baz = baz;
}
public int Bar
{
get { return _bar; }
}
public string Baz
{
get { return _baz; }
}
}
我发现自己写了很多看起来像这样的代码:
new Foo(7, "a");
其中 Foo
看起来像:
class Foo {
int bar;
string baz;
public Foo(int bar, string baz) {
this.bar = bar;
this.baz = baz;
}
}
受过 C# 培训的程序员将如何处理此问题?写 this.bar = bar
和 this.baz = baz
可以,但感觉很奇怪。
您可以使用对象初始化语法:
var foo = new Foo() { bar = 7, baz = "a" };
它要求您的字段为 public 并且属性具有 setter。
编译器会将其翻译成如下代码:
var temp = new Foo();
temp.bar = 7;
temp.baz = "1";
var foo = temp;
我会使用属性而不是字段 - 如果您需要向属性添加逻辑,将来修改起来会更容易。
class Foo
{
public int Bar { get; private set; }
public string Baz { get; private set; }
public Foo()
{
}
public Foo(int bar, string baz)
{
Bar = bar;
Baz = baz;
}
}
一个流行的约定是在私有字段名称前加上_
前缀,以区别于普通参数名称,例如
class Foo {
int _bar;
string _baz;
public Foo(int bar, string baz) {
_bar = bar;
_baz = baz;
}
}
那么就不需要使用 this
了。或者,由于您在问题标题中提到了 properties,您可以将这些字段封装在属性中并进行设置:
class Foo {
int _bar;
string _baz;
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar
{
get { return _bar; }
set { _bar = value; }
}
public string Baz
{
get { return _baz; }
set { _baz = value; }
}
}
由于 C# 有 case-sensitive 个符号名称,this
仍然是不必要的。现在,如果您没有对属性的 get/set 行为做任何比这更复杂的事情,您可以使用 auto-property 语法 :
class Foo {
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar { get; set; }
public string Baz { get; set; }
}
现在,如果您的共同需求是这些属性可以从外部读取 class 但只能从内部设置,您可以将它们设置为只读:
class Foo {
public Foo(int bar, string baz) {
Bar = bar;
Baz = baz;
}
public int Bar { get; private set; }
public string Baz { get; private set; }
}
但是如果您希望它们真正只在构造函数中设置,您可以返回使用字段:
class Foo {
readonly int _bar;
readonly string _baz;
public Foo(int bar, string baz) {
_bar = bar;
_baz = baz;
}
public int Bar
{
get { return _bar; }
}
public string Baz
{
get { return _baz; }
}
}