Использование base() в С#

Я изучал С# и хотел рассмотреть некоторые проекты с открытым исходным кодом, чтобы увидеть хороший код. Я нашел проект под названием Todomoo на sourceforge и там часть, которая меня озадачивает:

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);
    }

Ответы

Ответ 1

но класс не является производным классом

Класс является производным классом - он неявно наследует от System.Object. Неясно, почему кто-то будет ссылаться на конструктор base() для System.Object, хотя: он также делается неявным.

Что касается синтаксиса, я предполагаю, что С# принял синтаксис, близкий к спискам инициализаторов С++, а не к Java-вызову базовых конструкторов.

Ответ 3

Чтобы ответить на первый вопрос, все пользовательские классы наследуют, по крайней мере, от одного другого класса (Object). Это означает, что определение конструктора по умолчанию в качестве родительского конструктора почти всегда справедливо (это происходит не только тогда, когда объект наследуется более непосредственно из чего-то другого, у которого нет видимого конструктора по умолчанию). Однако в этом случае он избыточен; конструктор по умолчанию для базового класса будет вызываться, если он существует и доступен из дочернего элемента, не говоря уже об этом.

Во-вторых, в отличие от переопределения метода выбор варианта расширения функциональности конструктора базового класса невозможен. Конструктор базового класса должен быть вызван для инициализации членов данных в родительском объекте (к которому у вас может быть или нет доступа к дочернию), и это должно произойти до вызова дочернего конструктора (в случае, если дочерний элемент требует какой-либо родительской структуры для существовать). Таким образом, вместо того, чтобы разрешать вам вызывать конструктор базового класса, где бы вы ни находились, они заставляют вас определять тот, который вы хотите вызвать, когда этот конкретный дочерний конструктор используется, а среда выполнения будет обрабатывать когда и где.

Ответ 4

Вы не можете вызвать конструктор где-нибудь в вашем коде конструктора, потому что язык ограничивает это. В терминах промежуточного языка конструктор - это еще один вызов метода.

Ответ 5

Как указывали другие, все классы, полученные из 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();
    }
}

печатает

Foo

Foo2

Ответ 6

его конструктор extern, который строит его до того, как конструктор Category будет играть с ним, когда вы выполните base();, ничего не произойдет, потому что его конструктор и возвращает что-то и this = new base() приведет к ошибке