【问题标题】:Why does my static readonly member get instantiated multiple times?为什么我的静态只读成员多次实例化?
【发布时间】:2014-03-14 18:58:38
【问题描述】:

我在自定义类 Foo 中有一个 static readonly List<string> ValidatedProperties = new List<string>();,在 Foo 的构造函数中我调用了

protected Foo()
{
    foreach(var prop in properties)
    {
        ValidatedProperties.Add(prop.Name);
        Console.WriteLine(prop.Name);
    }
}

当我创建一个新的 Foo 时,它会按预期打印出来,但是,每次我创建一个新的 Foo 时它都会这样做。

每次创建另一个 Foo 对象时是否会重新编写 ValidatedProperties?还是因为Console.WriteLine而再次显示每个属性?

【问题讨论】:

  • 我不是 OP,但为什么投反对票?这个问题可能是基本的,但它格式正确、具体并且包含了 OP 尝试过的内容。如果我是初学者并且我搜索“静态成员被多次实例化”,这将是一个非常好的资源,这就是我认为投票系统的用途。
  • 究竟打算在这里做什么?每次创建Foo 的实例时,您都将properties 添加到相同的List<string>。所以Foo.ValidatedProperties 将包含Foo 的每个实例中所有属性的列表。那是你打算做的吗?您的 ValidatedProperties 仅被实例化一次。
  • @EvanL:我没有投反对票,但我不同意这是一个特别好的问题。 OP 没有多次实例化静态成员,并且可能对这里的实例化实际含义感到困惑。
  • @MattBurland 我同意 OP 可能混淆,但我认为问题的格式不值得 2 次反对。我们是否应该在每次有人感到困惑时投反对票,从而提出一个问题来澄清?然而,我确实认为简单搜索 static 的含义和 readonly 的含义可能会阻止这个问题。
  • @EvanL:就像我说的,我没有投反对票,但我也没有投赞成票。也许关闭更合适? (但我也没有投票)

标签: c# static readonly


【解决方案1】:

每次创建 Foo 的实例时,都会向 ValidatedProperties 添加一个条目。

只读意味着列表不能被另一个列表替换——这并不意味着列表的内容不能改变。

【讨论】:

  • 如果我不想想要添加新条目,const 会更合适吗?或者我应该将其保留为readonly,并在我打电话给我的foreach之前确保ValidatedProperties == null?什么是更好的做法?
  • @CharlesW 没有什么会起作用,因为 (a) 你需要一个只读的 LIST 和 (b) 这会在当前代码中引发错误。我会建议一本关于 C# 基础的书——你对静态和其他一些非常基本的东西有误解。
  • @CharlesW:也许你在这里寻找的是一个静态构造函数?是否要为 Foo 的所有实例提供一组属性?
【解决方案2】:

我有一种感觉,您正在尝试做的是有一个在Foo 的所有实例之间共享的单个列表,但仅填充一次。也许你想要一个静态构造函数:

static Foo()
{
    // note that properties needs to be static too!
    foreach(var prop in properties)
    {
        ValidatedProperties.Add(prop.Name);
        Console.WriteLine(prop.Name);
    }
}

public Foo()
{
    // regular constructor for creating an instance of Foo
}

虽然,除非 properties 来自某个外部来源(例如数据库、网络服务、文件),否则在声明 ValidatedProperties 时填充它会容易得多:

static readonly List<string> ValidatedProperties = new List<string>() { "foo", "bar" }

您甚至可以使用ReadOnlyCollection&lt;string&gt; 来防止任何人稍后添加:

static readonly ReadOnlyCollection<string> ValidatedProperties = 
    new ReadOnlyCollection<string>(new string[] {"foo", "bar" });

【讨论】:

  • 谢谢!我一定是解释得很糟糕。这正是我想要的。
  • properties = typeof(Foo).GetProperties(BindingFlags.Public | BindingFlags.Instance); 我这样做是因为 Foo(目前)是高度易变的,我不想每次在班级中添加或删除成员时都必须更新 ValidatedProperties。最终,我确定我会按照您的建议使用static readonly ReadOnlyCollection&lt;string&gt;。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2011-04-11
  • 2015-08-23
  • 2017-10-03
相关资源
最近更新 更多