8

我已经使用了很多自动属性,但我越来越远离设置具有在构造函数中初始化的只读支持字段的类。我删除了所有设置器,并且仅在属性明确需要设置器时才添加后面。

我发现这使我的课程更加健壮和优雅的面向对象,我因为没有早点这样做而自责。

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

4

3 回答 3

13

从对话中,我相信 C# 团队明白,他们使编写可变类型变得更容易,同时没有为不可变类型提供类似的好处。并不是说随着时间的推移它们使不可变性变得更加困难——它们只是没有让它变得更容易……除了匿名类型,它们是不可变的,但还有其他各种缺点。我当然不希望自动属性被带走——在合适的地方,它们真的很有用。我只想拥有只读属性的等效项(允许仅在构造函数中设置它们)。

我发现 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# 团队能感受到。但请记住,他们的资源有限,设计一种语言非常困难。

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

于 2010-09-03T23:06:58.917 回答
1

我删除了所有设置器,并且仅在属性明确需要设置器时才添加后面。我发现这使我的课程更加健壮和优雅的面向对象

我完全同意你的看法。我遇到了遗留代码,其中有很多用于某些类层次结构的对象初始值设定项。我需要添加一些属性,然后发现所有构造类实例的位置让我头疼。我第一次提交。现在我需要再添加一个属性。这太疯狂了!

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

于 2012-07-26T08:56:36.430 回答
0

我发现构造函数在 c# 代码示例中通常没有得到充分利用,我认为自动属性和对象初始化器是其中很大一部分

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

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

为什么 c# 团队会推动这样的功能,而不是更多地专注于交付推动最佳实践的功能

我认为引入对象初始化器是因为它们对于 Linq 是必需的:没有它们就无法创建匿名类型。至于自动属性,它们不那么重要,但它可能很容易实现,并且它可以为那些仅仅封装一个字段的属性节省时间。

于 2010-09-04T00:39:29.347 回答