在C#中使用base()

时间:2012-08-08 14:43:41

标签: c# constructor

我一直在学习C#,并希望查看一些开源项目以查看一些好的编写代码。我在sourceforge上找到了一个名为Todomoo的项目,其中有一部分令我感到困惑:

public class Category {

    // Note properties
    private int id = 0;
    private string name = "";
    private Color colour = Color.Gray;

    /// <summary>
    /// Create a new category.
    /// </summary>
    public Category() { }

    /// <summary>
    /// Load a category from the database.
    /// </summary>
    /// <param name="Id">ID of the category</param>
    public Category(int id) : base() {
        Load(id);
    }

这里它在其中一个构造函数中使用base(),但该类不是派生类。那究竟是什么呢?

为什么base()的语法是这样的,而不是像:

    public Category(int id) {
        base();
        Load(id);
    }

6 个答案:

答案 0 :(得分:17)

  

但该类不是派生类

该类是派生类 - 它隐式继承自System.Object。目前尚不清楚为什么有人会为base()调用System.Object构造函数:它也是隐式完成的。

就语法而言,我的猜测是C#采用了接近C ++初始化列表的语法,而不是基础构造函数的Java调用。

答案 1 :(得分:14)

C#中的每个类都是来自 System.Object 的派生类 Reference of Object in C#

答案 2 :(得分:3)

要回答第一个问题,所有用户定义的类都从至少一个其他类(Object)继承。这意味着将默认构造函数定义为父构造函数几乎总是有效的(不仅当对象更直接地从没有可见默认构造函数的其他东西继承时)。但是,在这种情况下,它是多余的;如果它存在并且可以从子进程访问,则将调用基类的默认构造函数,而不必这样说。

其次,与方法覆盖不同,选择是否以及在何处扩展基类构造函数的功能不是一种选择。必须调用基类的构造函数来初始化父级中的数据成员(您可能在子级中可以访问或不访问),并且此必须之前发生调用子构造函数(如果子项需要存在任何父结构)。因此,它们不是允许您在任何地方调用基类构造函数,而是强制您定义在使用此特定子构造函数时要调用的那个,并且运行时将处理时间和位置。

答案 3 :(得分:2)

您无法在构造函数代码中的某处调用构造函数,因为语言限制了这一点。就中间语言而言,构造函数只是另一种方法调用。

答案 4 :(得分:2)

正如其他人指出的那样,所有类都来自System.Object

在您的具体示例中,base()调用System.Object的默认构造函数。这实际上没有任何意义,因为即使未指定base(),也始终会调用基类的默认构造函数。

例如,以下代码

public class Foo
{
    public Foo()
    {
        Console.WriteLine("Foo");
    }
}

public class Foo2 : Foo
{
    public Foo2()
    {
        Console.WriteLine("Foo2");
    }
}

public class Program
{
    private static void Main(string[] args)
    {
        Foo2 d = new Foo2();

        Console.ReadKey();
    }
}

打印

  

     

foo2的

答案 5 :(得分:1)

它是一个extern构造函数,它在Category构造函数之前构造它,当你执行base();时,它将不会发生任何事情,因为它是一个构造函数并返回一些东西而this = new base()将导致错误