2015-12-31 11 views
12

は考えてみましょう:refフィールドを使って読み取り専用フィールドを変更できるのはなぜですか?

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" 

はどのようにこれはコンパイルすらない、それにもかかわらず動作しますか? readonlyとマークされているので、コンストラクターの外側の_valueフィールドに異なる値を割り当てることができません。しかし、それをrefでメソッドに渡してください。実際には操作できます。

危険ですか?どうして?それは私に間違っていると感じますが、私はそれに私の指を置くことはできません。

+0

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

上記のコードは非常に占いコンパイラエラーを提供します。有用な 'readonly'変数*は、少なくとも1回書く必要があります。それほど明白な詳細は、フィールドの初期化が実際にコンストラクタで行われ、C#コンパイラがコードを移動するということです。 –

答えて

19

コンストラクタ内のrefパラメータ(フィールドの設定が許可されている)として値を渡すだけなので、コンパイルされます。 Bar()への通話を他の方法に変更した場合、その通話は失敗します。すでに書かれたことは決してできない読み取り専用値が、それはdefaultをされ、存在するため

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

+0

かなり。 _valueは工事後に変更することも、外部に露出させることもできないので危険ではありません(あなたのgetアクセサを除いて) –

+0

ありがとうございます。どういうわけか、それは私によって滑りました。 :) –

関連する問題