Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can readonly fields be modified through ref parameters?

Tags:

c#

.net

ref

Consider:

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"

How does this even compile, nonetheless work? I should not be able to assign a the different value to _value field outside of the constructor, as it's marked with readonly. However, pass it by ref to a method, and it can indeed be manipulated.

Is this dangerous? Why? It feels wrong to me, but I can't quite put my finger on it.

like image 688
Matt Johnson-Pint Avatar asked Dec 31 '15 23:12

Matt Johnson-Pint


1 Answers

It compiles because you're only passing the value as a ref parameter in the constructor (where readonly fields are allowed to be set). If you moved your call to Bar() into some other method, it would fail.

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; }
    }
}

The above code provides a very telling compiler error:

A readonly field cannot be passed ref or out (except in a constructor)

like image 83
StriplingWarrior Avatar answered Oct 14 '22 18:10

StriplingWarrior