C#应该添加部分构造函数吗?

时间:2009-08-13 15:26:30

标签: c# .net

answer中的question让我对.NET框架设计选择感到疑惑。

.NET框架完全支持Partial classes, interfaces, and methods。有没有令人信服的理由支持部分构造函数没有以同样的方式添加?

这似乎可以简化部分类中的类构造。例如,由Windows Forms中的设计人员构建的表单构造函数可以直接在构造函数中使用表单构造代码,并将其拆分为两个文件。部分“Initialize()”方法似乎是一种有点常见的模式,在这种情况下可以简化。

我能看到的唯一潜在缺点是构造函数调用顺序缺乏确定性,但在许多情况下,部件的顺序无关紧要。如果是这样,你总是可以避免使用部分构造函数。

7 个答案:

答案 0 :(得分:14)

  

我能看到的唯一潜在缺点是构造函数调用顺序缺乏确定性,但在许多情况下,部件的顺序无关紧要。如果是这样,你总是可以避免使用部分构造函数。

这一部分对你的问题比看起来更重要。

如果您真的想了解C#语言是如何组合在一起的,那么您可以做的一件事就是关注Eric Lippert's博客。他从事Microsoft的C#语言工作,并且在选择资源有限的功能方面进行了大量讨论。阅读他的博客一段时间后,您将开始了解功能如何融入语言。

他曾在一些场合提到的一个因素是,对于该功能将要解决的问题是否已经有一个微不足道的解决方法。因此,回到问题的引用部分,您会提出两个要点:

  1. 缺乏决定论并没有很好的解决方案。如果您可以在帖子中提供优雅的解决方案,那么您将拥有更好的案例。
  2. 已经有一个微不足道的工作了。
  3. 把它们放在一起,这不是一个成功的功能。

答案 1 :(得分:10)

我会投赞成票,我会举一个具体的例子。

许多使用生成器(例如Linq To SQL)发出代码的技术将/必须发出默认构造函数。但是,我经常也想在构造函数中执行某些操作,例如连接到其中一个数据事件。

如果没有部分构造函数,我无法做到这一点,因为默认构造函数已经被生成的代码绑定了,我显然不想改变生成的代码来添加我的逻辑。

答案 2 :(得分:7)

嗯,partial类和接口是另一个故事。这个概念可以与partial方法相媲美。他们实际上什么都不做,只是告诉编译器这个方法可以存在于某个地方,如果它不删除方法调用。它不允许引入重复方法。

由于永远不会直接调用构造函数,因此拥有这样的概念没有任何意义。我相信当前的初始化模式在大多数情况下都能很好地工作。引入另一部分内容会不必要地使语言更复杂而不会带来显着的好处。

答案 3 :(得分:3)

我会投票否决。主要是因为你可以使用部分方法完成同样的事情,你试图用部分构造函数来完成而没有非威慑问题。

不要使用部分构造函数,而是让WinForms设计器在构造函数中运行。在生成的代码的末尾,发出一个部分方法并调用UserConstructor。然后,用户可以使用它进行初始化。

您甚至可以使用预订的部分方法来满足所有场景(BeginUserConstructor和EndUserConstructor)。

答案 4 :(得分:2)

部分方法不允许在两个单独的位置定义函数体的多个部分。它仅允许签名存在于一个文件中,并且实现可选地存在于另一个文件中。如果主体永远不会被定义,编译器将删除对该方法的引用。

就像Mehrdad说的那样......使用构造函数,你从来没有真正需要那种功能,因此它从未实现过。

答案 5 :(得分:1)

我希望看到许多与构造相关的功能,如果与部分构造函数结合使用会很有用;我不确定部分构造函数在没有它们的情况下会有多么有用。

  1. 能够指定是否应该在基类构造函数之前或之后初始化单个字段,具有后期初始化字段可以引用基础对象的特征,或者正在构造的对象的任何部分,这些部分在相同的源文件。
  2. 能够指定应使用相同名称的构造函数参数初始化某些字段;任何此类字段的声明都要求类的所有构造函数都包含具有匹配名称和类型的参数,或者通过一个具有匹配名称和类型的链。
  3. 能够指定一个类似参数初始化字段的变量,但只能在其他字段初始值设定项中使用。例如,如果一个类构造函数接受一个`Length`参数,该参数用于调整数组`x []`,`y []`和`z []`,那么如果可以使用这些数组构造这些数组将会很有用字段初始化语法。

如果在创建对象时将设置某些字段,并且此后从未修改过,那么组合初始化和声明似乎要比在代码的一部分中声明字段然后初始化要清晰得多。别的地方。此外,如果组合上述特性将允许类在调用基类构造函数之前初始化依赖于构造函数参数的字段 - 否则这是不可能的。

鉴于上述特性,我倾向于使用一种无​​参数的部分构造函数,它们将绑定到字段或字段组,这样字段就可以指定它们只能在指定的部分构造函数中写入(行为更严格)比readonly)。如果字段的值在类对象的整个生命周期中都是不变的,那么将其初始化逻辑附加到字段会更加清晰。

答案 6 :(得分:1)

我投赞成票是因为我最近遇到了一个需要部分构造函数的问题。

但是,我完全理解有关如何订购的问题。

在思考了这个问题几天后,我终于找到了一个可以满足我需求的解决方案。这是反思,但总比没有好。

// File1.cs
public partial class Example
{
    public Example()
    {
        // Add code here to find & invoke methods with custom attribute "Initialize".
    }

    [AttributeUsage(AttributeTargets.Method)]
    public class InitializeAttribute : Attribute
    {
        // Whatever you want here.
    }
}

// File2.cs
partial class Example
{
    [Initialize]
    public void RandomMethod()
    {
        // This will be run automatically with a new instance of the object.
        // It's just like it's part of the constructor.
        // There is no limit to these. You can have lots of generated code pages.
    }
}