什么是在建设期间设置成员的C#-idiomatic方式?

时间:2015-03-26 19:49:09

标签: c# constructor idiomatic

我发现自己编写了大量代码如下:

 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 = barthis.baz = baz有效,但感觉很奇怪。

3 个答案:

答案 0 :(得分:2)

一种流行的约定是使用_为私有字段名称添加前缀,将它们与常用参数名称区分开来,例如

class Foo {
      int _bar;
      string _baz;
      public Foo(int bar, string baz) {
           _bar = bar;
           _baz = baz;
      }
 }

因此不需要使用this。或者,由于您在问题标题中提到属性,您可以将这些字段封装在属性中并设置它们:

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#具有区分大小写的符号名称,因此this仍然不需要。现在,如果您没有使用属性的get / set行为执行比此更复杂的操作,则可以使用自动属性语法完全消除字段声明:

class Foo {
    public Foo(int bar, string baz) {
           Bar = bar;
           Baz = baz;
      }

    public int Bar { get; set; }

    public string Baz { get; set; }
}

现在,如果你有共同的要求,可以从课外读取这些属性,但只能从内部设置,你可以只读它们:

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; }
    }
}

答案 1 :(得分:1)

您可以使用对象初始化语法:

var foo = new Foo() { bar = 7, baz = "a" };

它要求您的字段为公共字段,并且要求属性具有设置器。

编译器会将其转换为以下代码:

var temp = new Foo();
temp.bar = 7;
temp.baz = "1";
var foo = temp;

答案 2 :(得分:0)

我使用属性而不是字段 - 如果您需要为属性添加逻辑,将来修改起来会更容易。

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;
      }
}