2016-11-04 3 views
1

私はこのルールを理解しています。しかし、なぜこれが分かっていますか?インデックスパラメータをrefパラメータとして渡せないのはなぜですか?

私のコードがある場合:

List<T> x = new List<T>; 
x.Add(new T()); 
x.Add(new T()); 
x.Add(new T()); 

int y = 2; 

//And I call a method 
M1(ref x[y]); 

のREF X [Y]関心のTの私のインスタンスへのポインタだけがそれではないですか?

私は非常に単純な方法でM1()というコード行を書くことができません。

。私は、C#の建築家がポインタを渡すために、この余分なステップを必要とする理由を聞くことを望んでい

T cX = x[y]; 
M1(ref cX); 

は私が回避策を知っていますか?それともコンパイラの制限ですか?

+1

'ref'と' out'は値ではなく場所に適用されます。 'x [y]'は 'T'型の値ですが、' cX'は 'T'を含む位置です。 – Lee

+0

既にこれについての[たくさんの質問](http://stackoverflow.com/questions/529782/c-sharp-property-and-ref-parameter-why-no-sugar)があります。そのリンク上の2番目の答えを見てください。 – Jonesopolis

答えて

3

インデクサー値は変数として分類されません。したがって、インデクサー値をrefまたはoutパラメーターとして渡すことはできません。

msdn

+0

ありがとうございます。私はインデクサーが私がそれを考える傾向があるよりもはるかに複雑であることを記事に書いていることを認めます。しかし、私は将来のC#コンパイラのリリースでこの構築制約がなくなるでしょう。それはより複雑で、同時に非常に簡単です。 – Steve

1

ref x[y]を参照してくださいには、関心のTの私のインスタンスへのポインタだけがそれではないでしょうか?

もし、Tが参照型であれば、はいです。 Tが値の型である場合はいいえ、それは問題ではありません。メソッドはref Tなので、Tのインスタンスへのポインタである変数への参照を受け入れる必要があります。あなたはポインタを持っているだけで、の格納場所ではなく、ポインタとしてです。 (私はあなたのアナロジーにとどまっていることに注意してください。技術的には、 "ポインタ"を持っていません。オブジェクトへの参照がありますが、この質問の目的のために類推すれば十分です)。

getterリストのインデクサの値が指定された値の格納場所に解決されない場合は、単なる値に解決されます。また、あなたが書くときに注意:あなたが戻っリストにcXの任意の変異を反映していないこと

T cX = x[y]; 
M1(ref cX); 

。あなたは記述する必要があると思います:

T cX = x[y]; 
M1(ref cX); 
x[y] = cX; 

実際にM1変数 CXへの変異がリストに反映されていることを保証するために同等であるために。

+0

それでは、なぜ私はcXのプロパティの値を変更すると、M1()から返った後にx [y]に永続化された変更ですか? – Steve

+1

@Steve参照によって参照されている値を変更しているため、参照自体に変更はありません。それが実際に起こっている場合は、最初に参照によってパラメータを渡すべきではありません。なぜなら、実際には参照を変更していないからです。 (参考としてパラメータを渡すのは非常に稀であることに注意してください;一般的にメソッドの適切な設計はまれです) – Servy

+0

ポインタは値を含むメモリ位置へのアドレスである値を含むメモリアドレスです興味を持っている。私は、そのオブジェクトのインスタンスのアドレスを含むメモリアドレスとしてオブジェクトへの参照を参照します。私にとってはまったく同じようです。あなたはそれを言語とは別にどのように見ますか? – Steve

関連する問題