Будет ли автоматически вызываться конструктор базового класса?

class Person
{
    public int age;
    public Person()
    {
        age = 1;
    }
}

class Customer : Person
{
    public Customer()
    {
        age += 1;
    }
}

Customer customer = new Customer();

Будет ли возраст клиента 2? Кажется, базовый классS конструктор будет называться независимо от того, что. Если так, зачем нам звонитьbase в конце иногда?

public Customer() : base()
{
    .............
}
 Ivan Li01 нояб. 2012 г., 14:33
Извини я нене понимаю это. Но это'Просто для уточнения моего вопроса.
 George Birbilis15 окт. 2018 г., 14:47
Нестатический является ключевым утверждением там, обратите внимание на это замечание относительно статических конструкторов:stackoverflow.com/questions/20092211/...
 Jeppe Stig Nielsen30 окт. 2016 г., 00:25
Если вы не укажете ни: base(...) ни: this(...) для нестатического конструктора по умолчанию: base() то есть конструктор базового класса с нулевым параметром. У вас это тоже с первым классомPerson где твойPerson() Конструктор неявно вызываетObject() конструктор базового класса. Пишу: base() (ноль аргументов) всегда избыточно. Также попробуйте ваш пример еще раз, гдеPerson Конструктор класса принимает один или несколько параметров.
 Jon B31 окт. 2012 г., 20:18
Технически,age является частным членом, так что нет компилировать. Это должно бытьpublicи т. д. на работу.

Ответы на вопрос(6)

но я обнаружил, что мне нужно вызвать MyConstructor (): base () без параметров в 1 случае. У меня есть базовый класс, который реализует INotifyPropertyChanged таким образом, что у меня есть виртуальная функция RegisterProperties (). Когда я переопределяю его, он вызывается в базовом конструкторе. Поэтому я вынужден вызывать его в самых последних производных подклассах, потому что база, очевидно, была вызвана до того, как был распознан переопределенный виртуальный объект. Мои свойства нене уведомлять, если я не сделаю этого. Весь базовый класс ниже.

Я добавил подкласс DatabaseTraits прямо под ним. Без пустого вызова base () мои свойства невызвать OnPropertyChanged ().

[DataContract]
public abstract class DataModelBase : INotifyPropertyChanged, IDataErrorInfo {

    #region Properties

    [IgnoreDataMember]
    public object Self {
        get { return this; }
        //only here to trigger change
        set { OnPropertyChanged("Self"); }
    }

    #endregion Properties

    #region Members

    [IgnoreDataMember]
    public Dispatcher Dispatcher { get; set; }

    [DataMember]
    private Dictionary<object, string=""> _properties = new Dictionary<object, string="">();

    #endregion Members

    #region Initialization

    public DataModelBase() {
        if(Application.Current != null) Dispatcher = Application.Current.Dispatcher;
        _properties.Clear();
        RegisterProperties();
    }

    #endregion Initialization

    #region Abstract Methods

    /// </object,></object,>
    /// This method must be defined
    /// (ref T property, string propertyName) {
        //causes problems in design mode
        //if (property == null) throw new Exception("DataModelBase.RegisterProperty : ref T property cannot be null.");
        if (_properties.ContainsKey(property)) return false;

        _properties.Add(property, propertyName);

        return true;
    }

    protected string GetPropertyName(ref T property) {
        if (_properties.ContainsKey(property))
            return _properties[property];

        return string.Empty;
    }

    protected bool SetProperty(ref T property, T value) {
        //if (EqualityComparer.Default.Equals(property, value)) return false;
        property = value;
        OnPropertyChanged(GetPropertyName(ref property));
        OnPropertyChanged("Self");

        return true;
    }

    [OnDeserialized]
    public void AfterSerialization(StreamingContext context) {
        if (Application.Current != null) Dispatcher = Application.Current.Dispatcher;
        //---for some reason this member is not allocated after serialization
        if (_properties == null) _properties = new Dictionary();
        _properties.Clear();
        RegisterProperties();
    }

    #endregion Behavior

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion INotifyPropertyChanged Members

    #region IDataErrorInfo Members

    string IDataErrorInfo.Error {
        get { throw new NotImplementedException(); }
    }

    string IDataErrorInfo.this[string propertyName] {
        get { throw new NotImplementedException(); }
    }

    #endregion IDataErrorInfo Members

} //End class DataModelBaseclass DataModelBase

/*I decided to add an example subclass*/
    [DataContract]
public abstract class DatabaseTraits : DataModelBase {
    #region Properties
    private long _id = -1;
    [DataMember]
    public long Id {
        get { return _id; }
        set { SetProperty(ref _id, value); }
    }
    private bool _isLocked = false;
    [DataMember]
    public bool IsLocked {
        get { return _isLocked; }
        set { SetProperty(ref _isLocked, value); }
    }

    private string _lockedBy = string.Empty;
    [DataMember]
    public string LockedBy {
        get { return _lockedBy; }
        set { SetProperty(ref _lockedBy, value); }
    }

    private DateTime _lockDate = new DateTime(0);
    [DataMember]
    public DateTime LockDate {
        get { return _lockDate; }
        set { SetProperty(ref _lockDate, value); }
    }

    private bool _isDeleted = false;
    [DataMember]
    public bool IsDeleted {
        get { return _isDeleted; }
        set { SetProperty(ref _isDeleted, value); }
    }
    #endregion Properties

    #region Initialization
    public DatabaseTraits() : base() {
        /*makes sure my overriden RegisterProperties() is called.*/
    }
    protected override void RegisterProperties() {
        RegisterProperty(ref _id, "Id");
        RegisterProperty(ref _isLocked, "IsLocked");
        RegisterProperty(ref _lockedBy, "LockedBy");
        RegisterProperty(ref _lockDate, "LockDate");
        RegisterProperty(ref _isDeleted, "IsDeleted");
    }
    #endregion Initialization

    #region Methods
    public void Copy(DatabaseTraits that) {
        Id = that.Id;
        IsLocked = that.IsLocked;
        LockedBy = that.LockedBy;
        LockDate = that.LockDate;
        IsDeleted = that.IsDeleted;
    }
    #endregion Methods
}
Решение Вопроса

как C # будет работать. Конструкторы для каждого типа в иерархии типов будут вызываться в порядке Most Base -> Самые производные.

Так что в вашем конкретном случае это вызываетPerson(), а потомCustomer() в конструкторе заказов. Причина, почему вам нужно иногда использоватьbase Конструктор - это когда конструкторам ниже текущего типа нужны дополнительные параметры. Например:

public class Base
{
     public int SomeNumber { get; set; }

     public Base(int someNumber)
     {
         SomeNumber = someNumber;
     }
}

public class AlwaysThreeDerived : Base
{
    public AlwaysThreeDerived()
       : base(3)
    {
    }
}

Для того, чтобы построитьAlwaysThreeDerived объект, он имеет конструктор без параметров. Тем не менееBase типа нет. Таким образом, чтобы создать конструктор без параметров, вам нужно предоставить аргумент базовому конструктору, который вы можете сделать с помощьюbase реализация.

 Pedro7727 мая 2014 г., 19:41
Странно, что Visual Studio показывает 0 ссылок на конструктор Base. Это может привести к неправильной интерпретации кода.
 Cloud17 сент. 2018 г., 13:33
Отличный ответ ...
 Tejs06 июн. 2014 г., 22:05
Я могу'не могу вспомнить случай, когда это будеттребуется вызвать конструктор без аргументов.
 Wonko the Sane31 окт. 2012 г., 20:51
То, что вы говорите, правда. Однако ничто не мешает Base иметь конструктор без параметров в дополнение к параметризованному конструктору, который задает SomeNumber, скажем, случайное число. AlwaysThreeDerived будет по-прежнему использовать вызов base (3), но другой класс (назовите его RandomDerived) может наследоваться от base без указания этого конструктора Base без параметров.
 Wonko the Sane31 окт. 2012 г., 21:25
Договорились (и +1). Просто неЯ не хочу скрывать это от самопровозглашенного новичка. :)
 Tejs31 окт. 2012 г., 21:05
Правильно - я просто приводил краткий пример наиболее часто используемой причины явного вызова базового конструктора.
 deworde06 июн. 2014 г., 14:56
Просто чтобы быть ясно, для "общедоступныйКонструктор>() : база()", base () совершенно лишнее, верно? Или есть случаи, когда вынужно специально вызывать конструктор без аргументов?

конструктор базового класса будет вызываться автоматически. Вам не нужно добавлять явный вызовbase() когда есть конструктор без аргументов.

Вы можете легко проверить это, распечатав возраст клиента после строительства (ссылка на Ideone с демо).

ЕКОТОРЫМ ПОДРАЗУМЕВАЕМЫМ ИЛИ ЯВНЫМ ВЫЗОВОМ НЕКОТОРОГО КОНСТРУКТОРА В БАЗОВОМ КЛАССЕ ИЗ ПРОИЗВОДНОГО КЛАССА.

Я не'Я не понимаю, как все это работает, пока я не осознаю этот факт.

Другими словами, когда вы подключаете базовый класс к производному классу, некоторый конструктор должен вызываться в базовом классе из производного. Базовый класс всегда создается первым из производного класса посредством вызова какого-либо конструктора в базовом классе. C # не делаетне волнует, если это конструктор по умолчанию или конструктор не по умолчанию с параметрами. Вот почему вы можете не указывать конструктор по умолчанию во всех ваших классах, так как он вызывается неявно ТОЛЬКО, ЕСЛИ в базовый класс не добавлен другой неконструктор с параметром (ами).

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

Позволять'проверить это .....

// THIS WORKS!!!
class MyBaseClass0
{
    // no default constructor - created automatically for you
}
class DerivedClass0 : MyBaseClass0
{
    // no default constructor - created automatically for you and calls the base class default constructor above
}

// THIS WORKS!!!
class MyBaseClass1
{
    // same as above
}
class DerivedClass1 : MyBaseClass1
{
    public DerivedClass1()
    {
      // here the derived class default constructor is created explicitly but the call to the base class default constructor is implicitly called
    }
}

// AND THIS WORKS!!!
class MyBaseClass2
{
    // as above
}
class DerivedClass2 : MyBaseClass2
{
    public DerivedClass2() : base()
    {
       // here we explicitly call the default constructor in the base class using base(). note its optional as base constructor would be called anyway here
    }
}

// AND THIS WORKS!!!
class MyBaseClass3
{
    // no default constructor
}
class DerivedClass3 : MyBaseClass3
{
    public DerivedClass3(int x)//non-default constructor
    {
       // as above, the default constructor in the base class is called behind the scenes implicitly here
    }
}

// AND THIS WORKS
class MyBaseClass4
{
    // non default constructor but missing default constructor
    public MyBaseClass4(string y)
    {

    }
}
class DerivedClass4 : MyBaseClass4
{
    // non default constructor but missing default constructor
    public DerivedClass4(int x) : base("hello")
    {
       // note that here, we have fulfilled the requirement that some constructor be called in base even if its not default
    }
}

// BUT THIS FAILS!!!...until you either add in a base() call to the non-default constructor or add in the default constructor into base!
class MyBaseClass5
{
    // 1. EITHER ADD MISSING DEFAULT CONSTRUCTOR HERE AND CALL IT USING base() below....
    public MyBaseClass5() { }

    // 2. Or use the non-default constructor and call to base("hello") below
    //public MyBaseClass5(string y)
    //{
    //}
}
class DerivedClass5 : MyBaseClass5
{
    public DerivedClass5(int x) : base()// 1. Either ADD explicit call here to explicit default constructor in base class
    {
    }

    //public DerivedClass5(int x) : base("hello")// 2. Or ADD explicit call here to parameter-based constructor in base class
    //{
    //}
}

Причина, по которой работают все вышеперечисленные элементы: 1. Вызов конструктора по умолчанию в базовом классе неявно создается в базовом классе и неявно вызывается из производного, потому что в базовый класс не был добавлен конструктор не по умолчанию. . Существует явный вызов нестандартного конструктора на основе параметров с использованием base (myparamter)

Какие'Непонятно, когда и почему конструкторы по умолчанию создаются в базовых классах и вызываются из производных классов. Это происходит, только если в базе НЕТ конструкторов, отличных от заданных по умолчанию

base() вызывается по умолчанию, но может использоваться для других целей, таких как:

Метод base () `используется для передачи значения в конструкцию родительского класса иливызвать конструктор без аргументов родительского класса.

например:

Случай 1: если у родителя есть параметризованный конструктор, но нет конструктора по умолчанию или без аргументов.

 class Person
 {

    private string FirstName;
    private string LastName;
    private string EmailAddress;
    private DateTime DateOfBirth;

    public Person(string firstName, string lastName, string emailAddress, DateTime dateOfBirth)
    {
        FirstName = firstName;
        LastName = lastName;
        EmailAddress = emailAddress;
        DateOfBirth = dateOfBirth;

    }
    }
class Employee : Person
{
    private double Salary { get; set; } = 0;

    public Employee(string firstName, string lastName, string emailAddress, DateTime dateOfBirth,double salary)
        :base(firstName,lastName,emailAddress,dateOfBirth)// used to pass value to parent constructor and it is mandatory if parent doesn't have the no-argument constructor.
    {
        Salary = salary;
    }
}

Случай 2: когда у родителя есть более одного конструктора вместе со стандартным.

class Person
{

    private string FirstName;
    private string LastName;
    private string EmailAddress;
    private DateTime DateOfBirth;

    public Person()
    {
        // some important intialization's to be done  

    }

    public Person(string firstName, string lastName, string emailAddress, DateTime dateOfBirth)
    {
        FirstName = firstName;
        LastName = lastName;
        EmailAddress = emailAddress;
        DateOfBirth = dateOfBirth;

    }
    }
class PermanentEmployee : Person
{
    public double HRA { get; set; }
    public double DA { get; set; }
    public double Tax { get; set; }
    public double NetPay { get; set; }
    public double TotalPay { get; set; }

    public PermanentEmployee(double hRA, double dA, double tax, double netPay, double totalPay) : base();
    {
        HRA = hRA;
        DA = dA;
        Tax = tax;
        NetPay = netPay;
        TotalPay = totalPay;
    }
}

Здесь мы вызываем конструктор no-arg вручную с помощью base () для выполнения некоторых операций, но немы передали любое значение.

Надеюсь, что это поможет вам.

тогда нужно будет вызвать его с параметрами:

class Person
{
    public Person(string random)
    {

    }
}

class Customer : Person
{
    public Customer(string random) : base (random)
    {

    }
}

Ваш ответ на вопрос