2010-10-03 42 views
5

我有这样的:为什么要使用初始值设定项? (.NET)

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有关?

此外:

有的回答说,正常的初始化可以留在“无效”状态后的对象,例如仅设置一个目录属性 - 在这里我的观察是,是谁的人正在设计的对象可能是设计的,它在只有真正输入的值才能通过真正的构造函数输入,而其他所有元素都可以在以后自由修改。

+0

嗯,好像我对lambda的预感是正确的! – 2010-10-03 13:19:27

+0

查看您最喜爱的C#语言书籍中的“匿名类型”。 – 2010-10-03 14:22:12

+0

@Hans:和'ad-hoc-property-containers'一样吗? – 2010-10-03 14:33:21

回答

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

使用对象initilizers,你可以清楚地看到这段代码的功能和对象不晚使用。

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

+0

好吧,这里是来自VB6的'with'关键字! :) – 2010-10-03 13:21:28

1

我相信这个语法已被添加,因为它更容易与lambda表达式一起使用,所以您可以轻松地做一些类似item => new Person() { Name = item.Name }的事情。

我不认为这有什么关系RAII虽然..

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

试着用旧的方式做这件事。它变得非常丑陋。

+0

+1。一个简单的点,但调用无参数构造函数时不需要派生类。 – Ani 2010-10-03 14:32:57

+0

@Ani:这就是为什么'新的AudioPlayer'没有禁忌:-) – Steven 2010-10-03 14:46:02

1

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

2

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

它唯一与RAII有关的是RAII依赖于明智的不变量,并且初始化器可以很容易地破坏不变量。

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

当一个类保持一个不变量时,那么以这种方式初始化它并不是一个好主意,并且作为一个规则,从一个构造函数重新写入新语法的值是一个坏主意。

在你的例子中,你的第一个例子并没有使用它的构造函数来初始化到一个有保证的有效状态。这是一种难闻的气味(在播放目录,开始时间和结束时间之前,播放器的目标是什么?),但是对于给定的类而言,这是合理的,那么使用新的语法也是如此。

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

2

在处理匿名类型时,初始化器变得必需,而不仅仅是有用。

例如为:

变种X =新的{富= “foo” 的,酒吧= “酒吧”};

+0

这个特殊的实例,是否与.net 2.0兼容?即它是IDE,编译器还是.net运行时的功能? – 2010-10-10 16:51:33

相关问题