1

Given the following code:

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")
    {
    }
}

The following output is produced:

Dog says: Hi, i'm a Cat!

Cat says: Hi, i'm a Cat!

Why? I would expect the Dog to say "Hi, i'm a Dog!"

Can someone a) explain to me this behaviour and b) let me know how i should update my code?

The real example is that i'm sharing an expensive property between concrete classes.

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • Remove `static` and made it `protected`. Static member not inheritable – Fabio Jan 30 '17 at 06:41
  • Possible duplicate of [C# static member "inheritance" - why does this exist at all?](http://stackoverflow.com/questions/2281775/c-sharp-static-member-inheritance-why-does-this-exist-at-all) – kgzdev Jan 30 '17 at 06:42
  • 1
    This makes perfect sense since static fields are actually members of a class, not an instance of a class. Hence, Dog and Cat which are objects will share those fields. – Darjan Bogdan Jan 30 '17 at 06:46

1 Answers1

1

You should become more familiar with static keyword. This article could be helpful.

Fields or properties marked static are belongs to class itself but not to instances of this class. When you create new instance of Dog the field _name initializes with "Dog" string. But when you creates new instance of Cat the field _name changes its value for "Cat" string.

As _name belongs to base Animal class, every instance of descendant class will be referenced to the same value.

You should remove the static modifier, if you want to make _name belongs to instances of classes and not to class itself.

Mikhail Tulubaev
  • 4,141
  • 19
  • 31
  • Understood, thanks for the answer. What if i want all instances of "Dog" to share the same property, and all instances of "Cat" to share their own property? How would i achieve that? – RPM1984 Jan 30 '17 at 21:58
  • If you want to have an unique single value for all Dog instances and an unique single value for all Cat instances - you can set static fields both in Dog and Cat. Although application behaviour will not be different if you will remove static modifier. It allows you to use this field in a base class. The first case with static fields in both classes will not allow to do it, and will look as bad smell code. Maybe, you want to use attributes instead of static field? – Mikhail Tulubaev Jan 31 '17 at 01:53