【问题标题】:Why is this static instance of the parent shared between new instances of children?为什么在新的子实例之间共享父的这个静态实例?
【发布时间】:2017-01-30 06:40:02
【问题描述】:

给定以下代码:

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

产生以下输出:

狗说:嗨,我是猫!

猫说:嗨,我是猫!

为什么?我希望狗会说“嗨,我是狗!”

有人可以 a) 向我解释这种行为并 b) 让我知道我应该如何更新我的代码吗?

真实的例子是我在具体类之间共享一个昂贵的属性。

【问题讨论】:

标签: c# singleton


【解决方案1】:

您应该更加熟悉static 关键字。 This article 可能会有所帮助。

标记为static 的字段或属性属于类本身,但不属于该类的实例。当您创建 Dog 的新实例时,字段 _name 使用 "Dog" 字符串进行初始化。但是,当您创建 Cat 的新实例时,_name 字段将其值更改为 "Cat" 字符串。

由于_name 属于Animal 基类,后代类的每个实例都将引用相同的值。

如果你想让_name 属于类的实例而不是类本身,你应该删除static 修饰符。

【讨论】:

  • 明白,感谢您的回答。如果我希望“Dog”的所有实例共享相同的属性,并且“Cat”的所有实例共享它们自己的属性怎么办?我将如何实现这一目标?
  • 如果您想为所有 Dog 实例设置唯一的单个值,并为所有 Cat 实例设置唯一的单个值 - 您可以在 Dog 和 Cat 中设置静态字段。尽管如果您删除静态修饰符,应用程序的行为不会有所不同。它允许您在基类中使用此字段。两个类中都有静态字段的第一种情况不允许这样做,并且看起来像臭味代码。也许,您想使用属性而不是静态字段?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2011-03-13
  • 2015-01-19
相关资源
最近更新 更多