为什么要使用初始化器呢? (。净)

时间:2010-10-03 13:05:03

标签: c# .net visual-studio-2008

我有这个:

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;

但我可以这样:

AudioPlayer player = new AudioPlayer
{
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

如果我转换为“新的写作方式”,除了不可读之外我还能获得什么?它会让我更接近lambda函数(=>)吗?

是否与RAII有关?

此外:

有些人回答说,正常的初始化可能会使对象处于“无效”状态,例如只设置一个Directory属性 - 我在这里观察的是设计对象的人可能是以只需要值的方式设计对象的真正输入的是通过真正的构造函数输入的,所有其他的都可以在以后自由修改。

6 个答案:

答案 0 :(得分:10)

通过这样一个简单的例子,你确实没有获得太多收益。但是,当你有这个时,情况会有所不同:

var player = new AudioPlayer
{
    Car = new Car()
    {
        WheelSize = new Inch(21),
        Driver = new Person()
        {
            Age = 53,
            Type = LicenseType.B,
            Family =
            {
                new Person("Jane"),
                new Person("Pieter"),
                new Person("Anny")
            }
        }
    }
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

尝试用旧方式执行此操作。它变得非常难看。

答案 1 :(得分:2)

考虑你想要将新创建的对象传递给某个方法(而不是用它做任何其他事情)。你可以用旧的方式写它:

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;
some.Method(player);

或者你可以使用对象初始化器:

some.Method(
  new AudioPlayer
  {
      Directory = vc.Directory,
      StartTime = vc.StarTime,
      EndTime = vc.EndTime
  });

使用对象启动器,您可以清楚地看到代码的作用以及以后不使用该对象。

另外,我认为可读性(和“可写性”)更好:你不必无休止地重复变量名。

答案 2 :(得分:2)

您不仅会获得不可读性,还可以通过将对象置于无效状态来获得更大的错误。

与RAII唯一的关系是RAII依赖于明智的不变量,初始化者可以很容易地打破不变量。

但是,它在创建匿名值或创建普通旧数据样式对象(其中类是值的“哑”容器和不变量不那么重要)时非常有用。这些对于lambda函数和linq表达式特别有用,但对它们来说既不是绝对必要的,也不限于它们。

当一个类维护一个不变量时,以这种方式初始化它并不是一个好主意,并且作为一项规则,从构造函数重写任何将值赋予新语法的构造都是一个坏主意。

在您的示例中,您的第一个案例不会使用其构造函数初始化为保证有效状态。这是一个难闻的气味,(玩家在拥有目录,开始时间和结束时间之前应该做什么?)但是当它对于给定的类合理时,那么使用新语法也是如此。

新语法可以在单个表达式中设置对象,而这个表达式又可以是另一个表达式的一部分,这可能是有用的,而且确实包含在lambda表达式中。

答案 3 :(得分:2)

在处理匿名类型时,初始化程序是必需的,而不仅仅是有用的。

e.g:

var x = new {Foo =“foo”,Bar =“bar”};

答案 4 :(得分:1)

我相信已添加此语法,因为它更易于与lambda表达式一起使用,因此您可以轻松地执行item => new Person() { Name = item.Name }之类的操作。

我不认为它与RAII有任何关系。

答案 5 :(得分:1)

您减少了21个字符的代码。代码越少意味着错误越少。为了获得更多,您可以使用隐式变量类型推断:var player = new AudioPlayer {