代码之家  ›  专栏  ›  技术社区  ›  terjetyl

c#构造函数与自动属性和对象初始化器

  •  8
  • terjetyl  · 技术社区  · 15 年前

    我经常使用auto属性,但是我越来越远离在构造函数中初始化带有只读备份字段的类。我移除了所有setter,并且只在属性明显需要setter时添加back。

    我发现这使我的课程更加健壮和优雅,而且我为自己没有早点这么做而感到懊恼。

    我发现构造函数在c代码示例中通常没有得到充分的使用,我认为自动属性和对象初始值设定项是其中的一个重要部分,所以我的问题是,为什么c团队会推出这样的特性,而不是更多地专注于交付特性,更多地推出最佳实践。一般来说,我认为写糟糕的代码太容易了,我相信可以做更多的工作来帮助程序员写好代码

    3 回复  |  直到 15 年前
        1
  •  13
  •   Jon Skeet    15 年前

    从对话中,我相信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 有趣的是,埃里克·利珀特、马兹·托格森、尼尔·加夫特(和我)进行了一次很棒的小组讨论,我对C#5的建议也出现在另一段视频中。

        2
  •  1
  •   Vadim Sukhorukov    13 年前

    我移除了所有setter,并且只在属性明显需要setter时添加back。 我发现这使我的类更加健壮和优雅

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

    为了限制对象初始值设定项的使用,我删除了无参数构造函数。

        3
  •  0
  •   Thomas Levesque    15 年前

    我发现构造函数在c代码示例中通常没有得到充分的使用,我认为自动属性和对象初始值设定项是其中的一个重要部分

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

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

    为什么c团队会推出这样的特性,而不是更多地关注交付特性,而更多地推出最佳实践

    我认为引入对象初始值设定项是因为它们是Linq所必需的:没有它们就无法创建匿名类型。至于auto属性,它们不那么重要,但是它可能很容易实现,而且对于那些只不过是封装字段的属性来说,它是一个实时的节省器。

    推荐文章