Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中调用基构造函数#_C#_Asp.net - Fatal编程技术网

C# 在C中调用基构造函数#

C# 在C中调用基构造函数#,c#,asp.net,C#,Asp.net,我有以下层次结构: class Base { public Base(string sMessage) { //Do stuff } } class Derived : Base { public Derived(string someParams) { string sMessage = "Blah " + someParams; //Here I want to call the base constructor //base(sMess

我有以下层次结构:

class Base
{
  public Base(string sMessage)
  {
     //Do stuff
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {

   string sMessage = "Blah " + someParams;

   //Here I want to call the base constructor
   //base(sMessage);

  }

}

你不能。您可以在之前调用它:

public Derived() : base()
或者你必须用钩子

class Base
{
  protected void init() { }
  public Base(string sMessage)
  {
     init();
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {
   string sMessage = "Blah " + someParams;
   init();
  }
}
你必须这样做。您也许可以将要在以后调用的代码放在基类中的受保护方法中,然后可以像这样在以后调用它:

class Base
{
  public Base(string sMessage)
  {
     ConstructorStuff();
  }

  protected Base()
  {
  }

  protected void ConstructorStuff()
  {
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {    
   string sMessage = "Blah " + someParams;

   ConstructorStuff();       
  }    
}

施工人员应注意的事项:

·构造函数不能是“虚拟的”

·它们不能被继承

·构造函数是按继承顺序调用的

public Child(string a):base(a){}

必须在派生类构造函数的主体之前调用基类构造函数

class Derived : Base
{
  public Derived(string someParams)
    : base("Blah " + someParams)
  {

  }

}

如果确实需要首先运行构造函数,那么我建议使用受保护的初始化方法,该方法由构造函数调用,并执行初始化类的实际工作。您需要提供一个备用构造函数,允许跳过初始化

public class Base
{

    public Base() : this(true) { }

    protected Base(bool runInitializer)
    {
        if (runInitializer)
        {
            this.Initialize();
        }
    }

    protected void Initialize()
    {
        ...initialize...
    }
}

public class Derived : Base
{
    // explicitly referencing the base constructor keeps
    // the default one from being invoked.
    public Derived() : base(false)
    {
       ...derived code
       this.Initialize();
    }
}

实际上,最简单的解决方案是:

class Base
{
  public Base(string sMessage)
  {
     //Do stuff
  }
}

class Derived : Base
{
  public Derived(string someParams)
    : base("Blah " + someParams)
  {
  }

}

为什么要把它弄得更复杂?

我最初错过了OregonGhost关于使用静态方法修改参数的评论,这对我来说是最有用的,所以我想我应该为阅读此线程的其他人添加一个代码示例:

class Base
{
    public Base( string sMessage )
    {
        // Do stuff
    }
}

class Derived : Base
{
    public Derived( string sMessage ) : base( AdjustParams( sMessage ) )
    {
    }

    static string AdjustParams( string sMessage )
    {
        return "Blah " + sMessage;
    }
}

既然基本构造函数应该做一些事情(可能是一些与sMessage有关的事情),那么这段代码如何解决他的问题呢?如果你使用钩子,你需要有一种避免调用默认基本构造函数的方法。请参阅我的答案,了解通过提供不运行初始值设定项的构造函数来避免此问题的方法。@wcm:我只是展示实现DotnetDude所需操作顺序的步骤。看起来他对C#非常了解,可以在这里修改参数并返回对象以满足他的实际需要。@Dinah——如果没有默认构造函数,这甚至无法编译。如果添加调用init()的默认构造函数,那么init()将被调用两次:一次在基构造函数中,一次在派生构造函数中。如果使用钩子实现,则需要有一个不运行它的构造函数。这将运行ConstructorStuff两次——一次是在派生构造函数之前调用默认基构造函数时,一次是在派生构造函数执行期间。Erm?Base没有调用ConstructorStuff的默认构造函数?啊。然后您需要提供一个默认构造函数,否则代码将无法编译,因为您的派生类将需要它。问题仍然存在,默认构造函数也需要使用ConstructorStuff,并且您需要一个不调用初始值设定项的替代方法。这将使我了解到,我遗漏了一个基本C#问题中的“太明显而不麻烦”代码。修改后的代码可以做他想做的事情,不是吗?现在的问题是每个派生类都需要调用初始值设定项。我认为您想要的是在默认情况下运行initialize,但在必要时有一种方法来阻止它。这可以完成任务,但不是IMO的最佳解决方案。对于这种简单的情况,这可能是最好的解决方案,但如果构造参数要复杂得多,它会很快变得难看。这是事实,尽管您也可以在静态方法中构造参数,并将结果传递给基类构造函数。我更喜欢这种方法。或者,由于这是.NET,您可以从构造函数中删除内容并在setters中执行,这是序列化友好的。是的,我注意到OregonGhost已经提出了这一点。。
class Base
{
    public Base( string sMessage )
    {
        // Do stuff
    }
}

class Derived : Base
{
    public Derived( string sMessage ) : base( AdjustParams( sMessage ) )
    {
    }

    static string AdjustParams( string sMessage )
    {
        return "Blah " + sMessage;
    }
}