最后从同一个类中的另一个构造函数调用构造函数

时间:2009-09-15 22:10:29

标签: c#

我在这里读到可以调用另一个构造函数Calling constructor from other constructor in same class

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

要求具体的人的更新: 在program.cs中,我希望能够根据某些上下文进行操作

要么:

// Form1 will show a message from its own private member
Application.Run(new Form1());

或者这个:

// Form1 will show a message from class1 member (kind of overloading form1 message if class1 exists)
Application.Run(new Form1(new Class1()));

I Form1我有

private string member = "Test Sample if no class1";

在class1中我有

private string member = "Test Sample from class1";
public string member;
{
    get { return this.member; }
    set { this.member = value; }
}

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

// of course Form1() could contain 100 lines of code
Form1() { MessageBox.Show(this.member); }

// I don't want to duplicate 100 lines in second constructor
// so I need to call first constructor
Form1(class1) {
    this.member = class1.member;
    // this is where I would now like to call Form1()
    // but the syntax below doesn't work
    this();
}

8 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:7)

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

答案 2 :(得分:7)

不,构造函数机制非常清晰和严格,你只能在你编写的那个之前“调用”另一个构造函数。

但你可以利用这个优势,只需改变你的想法(方法),使'last'构造函数成为用户调用的构造函数。要弄清楚具体细节,您必须发布一些示例代码。

编辑:

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

class Form1
{
   public Form1(Class1 c1)
   {
      if (c1 != null) this.member = c1.member;
   }

   public Form1() : this(null)
   {
   }
}

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

答案 3 :(得分:2)

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

Form1() : this(null)
{
}

Form1(Class1 class1)
{
    if (class1 != null)
    {
        this.member = class1.member;
    }

    ...
    MessageBox.Show(this.member);
    ...
}

答案 4 :(得分:2)

共享逻辑放在ConstructorFinished方法中。

Form1() {
  // Call the method to do the logic
  ConstructorFinished();
}



void ConstructorFinished()
{
   MessageBox.Show(this.member);
}



Form1(class1) {
    this.member = class1.member;

    // Call the method to do the logic
    ConstructorFinished();
}

答案 5 :(得分:2)

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

在您的具体情况下,只需遵循Microsoft已经使用设计器代码提供的模式。如果它对他们来说足够好......

public Form1() {
    InitializeComponent();
    InitializeComponentEx();
    MessageBox.Show(this.member);
}

public Form1(T class1) {
    this.member = class1.member;
    InitializeComponent();
    InitializeComponentEx();
}

private void InitializeComponentEx() {
    // my 100 lines of code
}

答案 6 :(得分:1)

对此的一般解决方案是将标准初始化代码放在主构造函数中,然后使用其他构造函数传递给它。由于你只是设置一个字符串,你可以这样做:

private const string DefaultValue = "some default value";
private string member;

Form1() : this(DefaultValue)
{

}

Form1(string overloadedStringAhoy) 
{
    this.member = overloadedStringAhoy;
}

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

我倾向于避免使用这些类型的构造函数,因为“哦,这必须按此顺序发生并且不会被设置”逻辑可以使维护变得更加困难。如果你遇到这个问题,请谨慎行事。 :)

在这种情况下,它是一个简单的设置,代码不会太复杂,它会做你需要的,所以我猜是的。如果您发现自己需要特殊情况+通过大量的初始化代码,那么使用简单的工厂或构建器类通常要好得多。这样,您可以使类构造函数代码尽可能简单,并将连接保留给工厂/构建器。

答案 7 :(得分:0)

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

您可以使用两种方法:

Pavel Minaev通过链接构造函数解决问题的完美答案 如果你的电话不是“处于中间”,可以使用这种方法。

Christian Hayter的完美答案通过将常规初始化移动到在所有构造函数中调用的单独方法来解决您的问题。这样你就可以在不同的构造函数中做任何你喜欢的事。