c#constructors vs auto-properties和object initializers

时间:2010-09-03 23:02:48

标签: c# automatic-properties object-initializers

我已经使用了很多自动属性但是我已经越来越远离那些使用构造函数中初始化的readonly支持字段设置类。我删除了所有的setter,只有在属性明显需要setter的情况下才添加。

我发现这使得我的课程更加健壮和优雅,而且我正在努力做到这一点。

我发现构造函数在c#代码示例中一般都没有得到充分利用,我认为自动属性和对象初始化程序是其中的一个重要部分,所以我的问题是为什么c#团队推送这样的功能而不是更多地关注交付推动最佳实践的功能更多。一般来说,我认为编写糟糕的代码太容易了,并且相信可以做更多的事情来帮助编码人员编写好的代码

3 个答案:

答案 0 :(得分:13)

通过对话,我相信C#团队理解他们更容易编写可变类型而不为不可变类型提供类似的好处。并不是说他们随着时间的推移变得更难以变得更难 - 他们只是没有让它变得更容易......除了匿名类型,这是不可改变的,但有其他各种缺点。我当然不希望将自动属性带走 - 在适当的地方,它们真的很有用。我只是想拥有readonly属性的等价物(允许它们只在构造函数中设置)。

我发现C#4的命名参数和可选参数使得构造不可变类型实例变得更容易 - 你仍然可以获得对象初始化器的许多好处,而没有可变性缺点。只需为您的类型的方面提供真正可选的默认值,将其余部分保留为必需的构造函数参数,并且调用者可以执行他们想要的操作 - 使用命名参数来增加清晰度。

不幸的是,收集初始化程序是一个难以破解的难题。我希望看到“链式”初始化器可以使用不可变集合,因此编译器可以创建对链接在一起的Add的调用,而不是在同一个实例上重复调用Plus

ImmutableList<string> x = new ImmutableList<string> { "a", "b", "c" };

会去:

ImmutableList<string> x = new ImmutableList<string>().Plus("a")
                                                     .Plus("b")
                                                     .Plus"(c");

当然,在框架中有更多不可变集合开始时会很好:)

当然,这对于汽车道具方面都没有帮助。我不得不承认我最近一直在欺骗一定数量,使用私人制定者伪装不变性:

public string Name { get; private set; }

这确实让我感觉很脏,但是当这是我的真实意图时,并没有让它真正真正不可变。

基本上,我说我感觉到你的痛苦 - 而且我很确定C#团队的确如此。请记住,他们的资源有限,设计语言很难。

你可能会发现videos from NDC 2010很有趣 - 与Eric Lippert,Mads Torgersen,Neal Gafter(和我)进行了一次精彩的小组讨论,而我对C#5的建议则在另一个视频中。

答案 1 :(得分:1)

  

我删除了所有的setter,如果属性显然需要setter,则只添加后面的内容。   我发现这使我的课程更加健壮和优雅OO明智

我完全同意你的看法。我面对遗留代码,其中有许多对象初始化器用于某些类层次结构。我需要添加一些属性然后我很头疼找到构建类实例的所有地方。 我第一次提交。现在我需要再添加一个属性。这太疯狂了!

为了限制对象初始化器的使用,我删除了无参数构造函数。

答案 2 :(得分:0)

  

我发现构造函数在c#代码示例中一般都没有得到充分利用,我认为自动属性和对象初始化程序是这个的重要部分

如果你的对象有很多属性,你显然不希望从构造函数中初始化它们。传递超过4或5个参数的信息对可读性来说是非常糟糕的(尽管Intellisense可以很容易地编写)。此外,如果您只想初始化一些属性并使用其他属性的默认值,则需要许多构造函数重载,或者必须将这些默认值显式传递给构造函数。

在这种情况下,对象初始化器非常方便,只要属性不是只读的(但是Jon指出,C#4中的可选参数是一个很好的选择)

  

为什么c#团队推动这样的功能,而不是更多地关注提供更多实践的交付功能

我认为引入了对象初始化程序,因为它们对于Linq来说是必需的:没有它们就无法创建匿名类型。至于自动属性,它们不那么重要,但它可能很容易实现,它可以实时节省属性,只做封装字段。