【问题标题】:Why can readonly fields be modified through ref parameters?为什么可以通过ref参数修改readonly字段?
【发布时间】:2016-04-05 18:31:12
【问题描述】:

考虑:

class Foo
{
    private readonly string _value;

    public Foo()
    {
        Bar(ref _value);
    }

    private void Bar(ref string value)
    {
        value = "hello world";
    }

    public string Value
    {
        get { return _value; }
    }
}

// ...

var foo = new Foo();
Console.WriteLine(foo.Value); // "hello world"

这如何编译,但仍然有效?我应该无法在构造函数之外为_value 字段分配不同的值,因为它标有readonly。但是,通过ref传递给方法,确实可以操作。

这很危险吗?为什么?对我来说感觉不对,但我不能完全理解它。

【问题讨论】:

  • 因为已经存在一个永远无法写入的只读值,所以它是default。一个有用的readonly 变量必须至少写一次。不太明显的细节是字段初始化实际上发生在构造函数中,C#​​ 编译器移动了代码。

标签: c# .net ref


【解决方案1】:

它可以编译是因为您只在构造函数中将值作为ref 参数传递(其中允许设置readonly 字段)。如果您将对 Bar() 的呼叫转移到其他方法中,它将失败。

class Foo
{
    private readonly string _value;

    public Foo()
    {
        Bar(ref _value);
    }

    public void Baz()
    {
        Bar(ref _value);
    }

    private void Bar(ref string value)
    {
        value = "hello world";
    }

    public string Value
    {
        get { return _value; }
    }
}

上面的代码提供了一个非常明显的编译器错误:

只读字段不能通过 ref 或 out(构造函数除外)

【讨论】:

  • 差不多。不危险,因为 _value 在构造后不能修改,也不会暴露在外部(除了你的 get 访问器)
  • 谢谢。不知何故,它从我身边溜走了。 :)
猜你喜欢
  • 2020-12-27
  • 2014-01-07
  • 2013-02-13
  • 2017-10-20
  • 2020-07-16
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
相关资源
最近更新 更多