2

我在这里看到,可以调用另一个构造函数从同一类中的其他构造函数调用构造函数

但它在开始时调用另一个构造函数,而我想在结束时调用。这可能吗?

针对要求具体信息的人员更新:在program.cs中,我希望能够根据上下文执行以下操作

要么这样:

//Form1将显示来自其私人成员的消息应用。运行(new Form1());

或者这样:

//Form1将显示来自class1成员的消息(如果class1存在,则是一种重载Form1消息)应用。运行(new Form1(new Class1()));

I Form1我有

private string member=“如果没有class1,则测试样本”;

在一班我有

private string member=“来自class1的测试样本”;公共字符串成员;{获取{return this.member;}设置{this.member=value;}}

在Form1中,我有这两个构造函数

//当然Form1()可以包含100行代码Form1(){MessageBox.Show(this.member);}//我不想在第二个构造函数中重复100行//所以我需要调用第一个构造函数表格1(类别1){this.member=class1.member;//这就是我现在要调用Form1()的地方//但以下语法不起作用this();}
4

8个答案8

重置为默认值
12

我不知道。您可能应该将最后需要执行的初始化代码移到一个单独的私有方法中,并在适当的情况下从两个构造函数调用该方法。

  • 在我想做什么的上下文中,我看不出这是怎么可能的,我想,看看我上面的代码。 评论 2009年9月15日23:13
  • 当然是。Form1(){init();}Form1(Class1 Class1){this.member=Class1.member;init( 评论 2009年9月15日23:51
  • 我认为这是最终的唯一解决方案,但我想知道为什么他们不允许调用默认构造函数,因为创建另一个init函数是人为的,需要重构代码。 评论 2009年9月16日7:02
7

不,构造函数机制非常明确和严格,您只能在编写构造函数之前“调用”其他构造函数。

但你可以利用这一点,只要改变你的想法(方法),让“最后一个”构造函数成为用户调用的构造函数。为了解决具体问题,您必须发布一些示例代码。

编辑:

有一些简单的解决方法,如:

类Form1{公共表格1(1类c1){如果(c1!=null)this.member=c1.member;}public Form1():this(null){}}

但不允许在另一个“内部”调用构造函数表单,这会产生更多问题。

0
7

不,如果使用构造函数链接,则始终首先调用基类构造函数。

2

正如其他人已经解释过的那样,这并不是它的工作原理。对于您的特殊情况,我可能会这样做:

Form1():this(null){}表格1(1类1类){if(class1!=空){this.member=class1.member;}...消息框。显示(this.member);...}
  • 这很好,但如果我想通过传递另一个类来扩展参数,我还必须更改Form1。 评论 2009年9月16日6:59
  • 2
    @程序员新手:是的,你会的,但通常构造函数只用于对象的基本初始化,而不是复杂的功能。因此,您可以在最完整的(可能也是最常见的)构造函数中执行所有需要的初始化,然后将其他构造函数链接到该构造函数。如果您稍后添加更多可以发送给构造函数的参数,这将是一个新的构造函数链接到原始的,但带有附加参数(这可能是错误规划的结果…)。
    – 敬畏
    评论 2009年9月16日7:59
  • 如果我的构造函数是关于动态生成可视化组件的,我没有选择,只能在构造函数中这样做。 评论 2009年9月19日8:04
2

共享逻辑放在构造函数已完成方法。

表格1(){//调用方法执行逻辑构造函数完成();}void构造函数完成(){消息框。显示(this.member);}表格1(类别1){this.member=class1.member;//调用方法执行逻辑构造函数完成();}
2
  • 是的,但我不明白为什么微软不允许调用默认构造函数,因为创建另一个充当默认构造函数的函数对语法来说是人为的,毫无用处。 评论 2009年9月16日7:05
  • 1
    如果可以像普通方法那样调用构造函数体,那么维护起来会很麻烦。很难根据顺序对不同行为的代码进行推理,尤其是当您将(不可避免地)让人们以不同的深奥方式使用它时。如果在构造函数中运行了大量复杂的代码,这通常表示出现了问题。 评论 2009年9月17日12:14
2

一般情况下,不支持。它不是C#语言或CLR支持的功能。

在您的特定情况下,只需遵循Microsoft已经为您提供的设计器代码模式。如果对他们来说足够好。。。

公共窗体1(){InitializeComponent();InitializeComponentEx();消息框。显示(this.member);}公共表格1(T类1){this.member=class1.member;InitializeComponent();InitializeComponentEx();}私有void InitializeComponentEx(){//我的100行代码}
1

通常的解决方案是将标准初始化代码放在主构造函数中,然后使用其他构造函数传递给它。因为您只设置了一个字符串,所以可以这样做:

private const string DefaultValue=“some default value”;私有字符串成员;Form1():this(DefaultValue){}Form1(字符串重载StringAhoy){this.member=重载字符串Ahoy;}

如果调用默认构造函数(Form1()),则只需将名称的默认值传递给重载构造函数。

我倾向于避免使用此类构造函数,因为用“哦,这必须按此顺序发生,而不能设置”的逻辑使它们复杂化会使维护更加困难。如果经常遇到这种情况,请小心行事

在这种情况下,这是一个简单的设置,代码不会变得太复杂,它可以满足您的需要,所以我想没关系。如果您发现自己必须使用特例+传递大量初始化代码,那么使用简单的工厂或构建器类通常会更好。这样,您可以使类构造函数代码尽可能简单,并将连接留给工厂/生成器。

  • 不,我不只是设置一个字符串,这只是一个示例,解决方案应该是通用的。 评论 2009年9月16日6:45
  • @程序员新手-这是通用的。Form1(字符串重载StringAhoy)可以包含任意类型的任意多个参数,而不仅仅是一个字符串重载StringAhoy.
    – 敬畏
    评论 2009年9月16日8:12
  • @程序员新手:这是一个通用的解决方案;我的回答也是“只是一个例子”。你应该能够从这个例子中推断。正如我所说,如果您有更复杂的构造逻辑,请查看工厂+构建器模式。使用这些模式,您可以使用一个简单的构造函数,并使用factory/builder对其进行参数化。如果你不满意,我建议你更新你的问题。 评论 2009年9月17日12:19
0

我不明白为什么这里的人的答案不能用在你的案例中。这并不依赖于构造函数的复杂性。

您可以使用两种方法:

完美答案帕维尔·米纳耶夫这通过链接构造函数解决了您的问题。
如果您的呼叫不在“中间”,则可以使用此方法。

完美答案克里斯蒂安·海特这通过将公共初始化移到一个在所有构造函数中调用的单独方法来解决问题。这样,您可以在不同的构造函数中执行任何操作。

1
  • 答案没问题,我得选一个。 评论 2009年9月19日8:05

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.