我一直在学习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);
}
答案 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()
将导致错误