什么是基类构造函数,为什么我要使用它? (附例)

时间:2016-08-11 18:26:41

标签: c# asp.net .net asp.net-mvc entity-framework

我目前正在开发一个ASP.NET核心MVC应用程序(我正在将项目从.NET迁移到.NET Core),我想知道基础构造函数。

具体来说,代码如下:

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base("name=CompanyFormsContext")
    {
    }

    public CompanyFormsContext(string connName)
        : base("name=" + connName)
    {
    }
...
}

这是一种ASP.NET语法,现在DbContext不接受字符串作为参数,而是接受DbContextOptionsBuilder。

我的问题是:基类构造函数如何以及何时有用?在这里,我可以为CompanyFormsContext创建一个空的构造函数,但我仍然可以为基类构造函数传递一个参数?

我猜测基本构造函数与DbContext有关,因为CompanyFormsContext是子类。但是,我很困惑为什么我可能想在这里使用基类。

以下是我们在项目中调用这些方法的两种方法:

        //First
        var db = new CompanyFormsContext(siteUrl.StartsWith("http://www.") ? "CompanyFormsContext" : "CompanyFormsContextQA");
        //Second
        var env = Request.Headers["environment"].First();
        var db = new CompanyFormsContext(env);

我可能不得不以他们使用新的.NET Core语法的方式修改它们。将为每个实例调用哪个构造函数?

很快,我想了解在这种情况下如何使用基类以及它们的一般用途。感谢

4 个答案:

答案 0 :(得分:3)

如果在许多不同的场景中使用了某种初始化,则使用基类构造函数。例如,如果您有类似

的内容
public bool Abc { get; set; }

private readonly string x;

private readonly string newName;

public Test(string x, string newName)
{
   Abc = true;
   thix.x = x;
   this.newName = newName;
}

(是的,非常愚蠢的例子,但无论如何)你总是希望初始化发生你可能不希望每次你有一个新的派生类时反复输入。这不仅令人讨厌,从维护的角度来看也是不好的;如果由于某种原因你不得不改变逻辑,那么你必须去你键入它并改变它的每一个地方,如果你不小心错过了一个,你就会在你的系统中引入一个错误。

请注意,父类型和派生类型都可能有多个构造函数。例如:

public abstract class SomeClass
{
    public SomeClass(string a, string b)
    {
       // ...
    }

    public SomeClass()
    {
      //...
    }
}

public SomeDerivedType : SomeClass
{
     public SomeDerivedType(string a, string b) : base(a, b)
     {
         // ...
     }

     public SomeDerivedType() : base("test", "string")
     {
        // ..
     }
}

基本构造函数和派生类型构造函数具有不同的参数是完全有效的。如果你仔细想想,这是有道理的;你正在调用一个完全不同的构造函数。例如,完成以下操作将非常有效:

public SomeDerivedType()...
{
   // The CollectionType constructor has a different number of parameters than SomeDerivedType does
   abc = new CollectionType<int>(1, 2, 3, 4, 5);
}

答案 1 :(得分:1)

在MSDN上查看https://msdn.microsoft.com/en-us/library/ms173115.aspx

  

在派生类中,如果未使用base关键字显式调用基类构造函数,则会隐式调用默认构造函数(如果有)。这意味着以下构造函数声明实际上是相同的:

...

  

如果基类不提供默认构造函数,则派生类必须使用base对基础构造函数进行显式调用。   构造函数可以使用this关键字在同一对象中调用另一个构造函数。与base类似,可以使用或不使用参数,构造函数中的任何参数都可以作为参数或作为表达式的一部分使用。例如,上一个示例中的第二个构造函数可以使用以下函数重写:

答案 2 :(得分:0)

使用字符串参数调用构造函数。因此,执行接受字符串的那个。基类的构造函数也由于:base()。

而执行

如果要在该构造函数中执行代码,通常使用基础构造函数。并且您不能或不想将该代码复制到childconstructor。除非您不希望执行基础构造函数代码,否则始终存在。你可以通过不使用base()

来覆盖它

答案 3 :(得分:0)

来自https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx

public class BaseClass
{
    int num;

    public BaseClass()
    {
        Console.WriteLine("in BaseClass()");
    }

    public BaseClass(int i)
    {
        num = i;
        Console.WriteLine("in BaseClass(int i)");
    }

    public int GetNum()
    {
        return num;
    }
}

public class DerivedClass : BaseClass
{
    // This constructor will call BaseClass.BaseClass()
    public DerivedClass() : base()
    {
    }

    // This constructor will call BaseClass.BaseClass(int i)
    public DerivedClass(int i) : base(i)
    {
    }

    static void Main()
    {
        DerivedClass md = new DerivedClass();
        DerivedClass md1 = new DerivedClass(1);
    }
}
/*
Output:
in BaseClass()
in BaseClass(int i)
*/

这里我意识到,如果没有DerivedClass中的信息,则调用BaseClass构造函数。因此,对于我的问题:

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base("name=CompanyFormsContext")
    {
    }

    public CompanyFormsContext(string connName)
        : base("name=" + connName)
    {
    }
...
}

在两种情况下都会调用DbContext(字符串),但在一种情况下,输入参数为"name=CompanyFormsContext",另一种情况下为"name=" + connName

因此,为了能够使用.NET Core语法更改为DbContextOptionsBuilder参数,我可以定义两个OptionsBuilders实例,然后根据CompanyFormsContext的输入在基础构造函数中调用它们。

我相信这正是我所寻找的,而且我能够得到其他答案。完成后,我会改进答案并分享完整的代码。