初始化C#自动属性

初始化C#自动属性,c#,initialization,automatic-properties,C#,Initialization,Automatic Properties,我习惯于写这样的课: public class foo { private string mBar = "bar"; public string Bar { get { return mBar; } set { mBar = value; } } //... other methods, no constructor ... } 将Bar转换为auto属性似乎既方便又简洁,但如何在不添加构造函数并将初始化放在其中的情况下保留初始化 public class fo

我习惯于写这样的课:

public class foo {
  private string mBar = "bar";
  public string Bar {
    get { return mBar; }
    set { mBar = value; }
  }
  //... other methods, no constructor ...
}
将Bar转换为auto属性似乎既方便又简洁,但如何在不添加构造函数并将初始化放在其中的情况下保留初始化

public class foo2theRevengeOfFoo {
  //private string mBar = "bar";
  public string Bar { get; set; }
  //... other methods, no constructor ...
  //behavior has changed.
}
您可以看到,添加构造函数并不符合我从自动属性中获得的工作节省

这样的事情对我来说更有意义:

public string Bar { get; set; } = "bar";

在默认构造函数中(以及任何非默认构造函数,如果您也有):


我相信这与您的原始代码的性能相同,因为这是在幕后发生的。

您可以通过类的构造函数来实现:

public class foo {
  public foo(){
    Bar = "bar";
  }
  public string Bar {get;set;}
}
如果您有另一个构造函数(即,一个接受参数的构造函数)或一组构造函数,则始终可以有以下内容(称为构造函数链接):


如果总是将调用链接到默认构造函数,则可以在那里设置所有默认属性初始化。当链接时,链接的构造函数将在调用构造函数之前被调用,这样您更专业的构造函数将能够根据需要设置不同的默认值。

更新-下面的答案是在C#6出现之前编写的。在C#6中,你可以写:

public class Foo
{
    public string Bar { get; set; } = "bar";
}
您还可以写入只读的自动实现属性,这些属性只能在构造函数中写入(但也可以指定默认初始值):


不幸的是,现在没有办法做到这一点。必须在构造函数中设置值。(使用构造函数链接有助于避免重复。)

自动实现的属性现在很方便,但肯定会更好。我发现自己不需要像自动实现的只读属性那样频繁地进行这种初始化,而只读属性只能在构造函数中设置,并由只读字段支持

这在C#5之前(包括C#5)都没有发生过,但在C#6中正在计划中——既允许在声明时初始化,也允许在构造函数体中初始化只读自动实现的属性。

这在C#6.0中是可能的:


你不想在构造器中做这件事有什么特别的原因吗?因为我觉得这是个很自然的地方。只是因为我以前不需要在构造器中做这件事。因此,如果我必须添加一个构造函数,这不会节省我的任何精力。如果它是静态私有字符串呢。。。?然后,您不希望在构造函数中初始化,因为每次创建新对象时都会调用它,而这并不是您想要的~~~这个问题有点老了,但要回答@StevePitchers和dlamblin,您可以创建一个静态构造函数来初始化静态属性,只需一次…@GarryShutler,我找到了一个不想在构造函数中初始化属性的有效原因:如果属性被标记为
virtual
,并且在派生类中被重写,它可能需要不同的初始化逻辑。由于基本构造函数中的初始化代码调用属性setter,而不是直接设置支持字段,因此派生类必须避免使用
base()
构造函数,以避免触发默认初始化逻辑。看起来是个滑坡。嗯,我想我真的展示了三种方法,不是吗p最后一个示例有点误导,因为内联初始化导致变量在其他构造函数逻辑之前被初始化。您的模式导致初始化在正常构造函数逻辑之后发生(至少在示例3中,对于int-something构造函数是这样)。DefaultValueAttribute不设置属性的值。它所做的只是告诉VisualStudio默认值应该是什么,这样在属性窗口中,如果未设置该值,则将以粗体显示。它不会以任何方式更改值。+1 James>>MSDN:“DefaultValueAttribute不会导致成员自动使用该属性的值初始化。您必须在代码中设置初始值。”此答案确实应该更新以删除DefaultValue建议,因为它不会如图所示工作。如果您有多个不同的构造函数,与只初始化基础字段和不使用自动属性相比,这将需要更多的工作-我真的不知道在那种情况下,您从自动属性中获得了什么好处…这是有区别的,但是:立即初始化意味着它甚至在默认构造函数之前就已经初始化了。我最近有一个应用程序,由于一些奇怪的原因,我不明白这一点实际上很重要。这是VB.NET团队做对的地方之一——在VB中,您可以声明您的属性并将其设置在同一行中,如下所示:
公共属性MyProp As String=“asdf”
。不幸的是,您不能像在C#中那样声明公共getter和私有setter。不确定为什么两个团队都无法正确实现此功能。@mattmc3:他们几乎做到了。出于某种原因,它们不允许初始化的只读自动属性,即使在语义上它们比初始化的读写属性更有意义。“Jon Skeet已经写了一本关于C#5.0的书;它现在被封存了。三年后,Anders Hejlsberg将打开这本书,看看语言设计团队是否做对了。”@poke:Done…虽然我不打算像这样更新我的所有答案:)Resharper为我建议了这个。我说,当然,把它移到初始值设定项,然后我找不到它。呵呵。#程序员问题
public class foo {
  private foo(){
    Bar = "bar";
    Baz = "baz";
  }
  public foo(int something) : this(){
    //do specialized initialization here
    Baz = string.Format("{0}Baz", something);
  }
  public string Bar {get; set;}
  public string Baz {get; set;}
}
public class Foo
{
    public string Bar { get; set; } = "bar";
}
public class Foo
{
    public string Bar { get; }

    public Foo(string bar)
    {
        Bar = bar;
    }
}
public int Y { get; } = 2;