2012-06-04 6 views
-2

Вызов базового конструктора из дочернего конструктора - лучшая практика? Здесь находится abstract class.Вызов базового конструктора из дочернего конструктора

Вот пример кода

abstract class MyBase 
{ 
    String l_strChildName; 
    public MyBase(String Name) 
    { 
     l_strChildName = Name; 
    } 

    public abstract void func(); 
} 

class MyChild_One : MyBase 
{ 
    public MyChild_One() : base("MyChild One") { } 

    public override void func() 
    { 

    } 
} 

class MyChild_Two : MyBase 
{ 
    public MyChild_Two() : base("MyChild Two") { } 

    public override void func() 
    { 

    } 
} 

Является ли этот механизм вызова является наилучшей практики?

+3

По сравнению с чем? –

+0

@FyodorSoikin: Мне просто нужно знать, рекомендуется ли это практика или нет? –

+1

Ваш вопрос очень широк - если структура позволяет вам это сделать, тогда всегда будет ситуация, в которой это уместно.Если ваш класс _needs_ 'l_strChildName' должен быть заполнен для того, чтобы функционировать, и если он будет иметь другое значение в каждом производном классе, то да, это хорошая идея, чтобы вызвать базовый конструктор, поскольку он гарантирует, что вы не можете случайно оставите важное поле неинициализированным. Однако, вероятно, хорошая идея сделать такое поле неизменным, используя ключевое слово 'readonly'. –

ответ

2

Базовый класс должен, по дизайну, инкапсулировать функциональность, которая будет общей для всех производных классов (так как она будет унаследована ими). Если поле/свойство, которое вы инициализируете с помощью конструктора базового класса, имеет отношение к инициализации всех производных классов, то да, передача его в конструктор базового класса с помощью ключевого слова base является правильным подходом.

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

Я предполагаю, что приведенный вами пример надуман ради вопроса. Вы должны не hard-code имя класса; Вы можете использовать GetType метод (или is ключевое слово) для определения фактического типа данных экземпляра во время выполнения:

MyBase x = new MyChild_One(); 
Console.WriteLine(x.GetType().Name); // Outputs "MyChild_One" 

Для полея/свойств, значения которых никогда не изменится, вы можете также использовать абстрактное свойство только для чтения что перекрывается всеми производными классами:

abstract class MyBase 
{ 
    public abstract String l_strChildName { get; } 
} 

class MyChild_One : MyBase 
{ 
    public override String l_strChildName 
    { 
     get { return "MyChild One"; } 
    } 
} 

class MyChild_Two : MyBase 
{ 
    public override String l_strChildName 
    { 
     get { return "MyChild Two"; } 
    } 
} 
+0

Целью не является получение имени дочернего элемента, но для инициализации некоторых объектов в базе (в моем проекте) –

+1

Вам нужно «попробовать» тип среды выполнения. Если вашему базовому классу нужны знания о типе времени выполнения объект производного класса есть что-то подозрительное в дизайне. –

+0

@ RuneFS: Хорошая точка. Инициализация, на которую влияет тип производного класса, должна быть реализована в переопределенных методах (или их производных конструкторах). – Douglas

1

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

0

Поскольку существует только один конструктор для базового класса, то имеет, чтобы позвонить ему.

Если бы было несколько определенных, вы могли бы выбрать, какой из них вызывать.

Если базовый класс имеет конструктор по умолчанию, вы и опускаете его явно. Например.

: base() 

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

1

Базовый конструктор класса всегда вызывается перед выполнением собственного конструктора класса. «: Base (value)» синтаксис - это просто способ передачи ему параметров, если вы хотите вызвать конструктор по умолчанию, который вам не нужно писать «: base()», он будет вызван в любом случае.

0

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

+0

Это не только лучше в этом случае –

Смежные вопросы