2017-01-30 2 views
1

Учитывая следующий код:Почему этот статический экземпляр родителя делится между новыми экземплярами детей?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var dog = new Dog(); 
     var cat = new Cat(); 

     dog.Print(); 
     cat.Print(); 

     Console.ReadKey(); 
    } 
} 

public abstract class Animal 
{ 
    private static string _name; 

    protected Animal(string name) 
    { 
     _name = name; 
    } 

    private static string _hi; 
    private string SayHi() 
    { 
     return _hi ?? (_hi = $"Hi, i'm a {_name}!"); 
    } 

    public void Print() 
    { 
     Console.WriteLine($"{this.GetType().Name} says: {SayHi()}"); 
    } 
} 

public class Cat : Animal 
{ 
    public Cat() : base("Cat") 
    { 
    } 
} 

public class Dog : Animal 
{ 
    public Dog() : base("Dog") 
    { 
    } 
} 

Следующий вывод производится:

Собака говорит: Привет, я кот!

Cat говорит: Привет, я кот!

Почему? Я ожидал, что собака скажет: «Привет, я собака!»

Может кто-нибудь а) объяснить мне такое поведение и b) сообщить мне, как я должен обновлять свой код?

Настоящим примером является то, что я разделяю недвижимость между конкретными классами.

+0

Удалить 'static' и сделать его« защищенным ». Статический член не наследуется – Fabio

+0

Возможный дубликат [C# static member "inheritance" - почему это вообще существует?] (Http://stackoverflow.com/questions/2281775/c-sharp-static-member-inheritance-why-does -this-exist-at-all) –

+1

Это имеет смысл, поскольку статические поля на самом деле являются членами класса, а не экземпляром класса. Следовательно, Dog и Cat, которые являются объектами, будут делиться этими полями. –

ответ

1

Знайте ближе к static ключевым словам. This article может быть полезно.

Поля или свойства, отмеченные знаком static, относятся к классу, но не к экземплярам этого класса. При создании нового экземпляра Dog поле _name инициализирует строку "Dog". Но когда вы создаете новый экземпляр Cat, поле _name меняет свое значение на строку "Cat".

В качестве _name принадлежит базовому классу Animal, каждый экземпляр класса потомка будет ссылаться на одно и то же значение.

Вы должны удалить модификатор static, если хотите, чтобы _name принадлежал к экземплярам классов, а не к самому классу.

+0

Понял, спасибо за ответ. Что делать, если я хочу, чтобы все экземпляры «Собака» делились одним и тем же свойством, и все экземпляры «Cat» делились своим собственным имуществом? Как я могу это достичь? – RPM1984

+0

Если вы хотите иметь уникальное единственное значение для всех экземпляров Dog и уникальное одиночное значение для всех экземпляров Cat - вы можете установить статические поля как в Dog, так и в Cat. Хотя поведение приложения не будет отличаться, если вы удалите статический модификатор. Он позволяет использовать это поле в базовом классе. Первый случай со статическими полями в обоих классах не позволит это сделать, и будет выглядеть как плохой код запаха. Может быть, вы хотите использовать атрибуты вместо статического поля? –

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