2011-08-04 19 views
3

outまたはrefパラメータを使用するメソッドを呼び出す場合、そのメソッドを呼び出すときにoutまたはrefでパラメータをマークする必要があるのはなぜですか?paramsの先頭にoutまたはrefを付ける必要があるのはなぜですか?

void DoStuff(int x, out int y) 
{ 
    y = x + 1; 
} 

void DoStuff(int x, ref int y) 
{ 
    y = x + 1; 
} 

その後、Visual Studioは、「それので、オーバーロードされたメソッド 『DoStuff』を定義することはできません報告します。私は、これは、オペレータがオーバーロードしたときにあいまいさを軽減するものだったが、私はそうのような2つのメソッドを作成した場合思っていたすなわち

DateTime.TryParse(myDate, out dateLogged) 

他の方法とはrefとoutだけが異なる」と私はとにかくできませんでした。

EDIT:2つのオーバーロードされたメソッドがあった場合、私はメソッドを呼び出すときに出て指定するか、または参照する必要があると思わもう少し研究した後

はこのように宣言:

void DoStuff(int x, out int y) 

    void DoStuff(int x, int y) 
+1

あなたは本当にそれが暗黙的であることを望んでいません。予期しない変数変更の可能性を考慮してください。 – Jodrell

+0

これはまたrefを見苦しく見せて、その人気を低下させ、コードをより保守しやすくするという利点があります。 (IMO) – Jodrell

答えて

10

これは、呼び出すメソッドが変数自体の値を変更する可能性があることに明示的に同意しているためです。これはC#の言語要件です。 VB.NETのような他の言語では、実際のメソッド呼び出し、メソッドシグネチャのみをデコレートする必要はありません。

+0

確かに、これはC# – Jodrell

+0

の肯定的な特徴の一つです。ありがとうございました。私の例の2つのメソッドシグネチャを次のように変更した場合: void DoStuff(int x、out int y) void DoStuff(int x、int y) これらはオーバーロードされます。 – GrandMasterFlush

+1

@グランド:はい。 ILは 'ref'と'out'を区別しません。なぜなら、' ref'を持つオーバーロードと 'out'だけのオーバーロードを作成できないのですが、' ref'と ' out 'パラメータとそうでないパラメータとの両方を含む。 –

0

あなたのケースはハックとみなされる可能性があります。メソッドの引数の値を変更できるようにするのが目的です。例えば

void someMethod(ref i) 
{ 
i = 1; 
} 


int i = 0; 
someMethod(ref i); //i now becomes 1, without the ref it would stay 0. 
+0

彼はなぜ関数を呼び出すときに 'ref'または' out'を使う必要があるのか​​を質問しています( 'ref'または' out'をメソッドのシグネチャに 'ref'または' out'として宣言するだけでなく) 「out」は行います。 –

+0

私の悪い、あなたの答えをupvoted :) – TJHeuvel

+0

@TJHeuvel申し訳ありませんが、私の質問は明らかに私がそれを意味したように明らかにされていない! – GrandMasterFlush

2

が参考とアウトが実際には同じものです。違いは、outキーワードは、メソッドから戻る前に変数が割り当てられていることをコンパイラがチェックするようにすることです。

EDIT

申し訳ありませんが、ご質問、私はC#は、パラメータ修飾子の唯一の違いは、あなたが同じシグネチャを持つ2つの方法を持つことができないだろう、なぜあなたが求めていたと思ったが誤解。 @Adam Robinsonの答えを見てください。メソッドから返された後に、呼び出し元が何が起こるかを知るようにします(または、は、その場合はが発生します)。

+2

彼は関数を呼び出すときに 'ref'または' out'を使う必要があるのか​​と質問しています( 'ref'や' out'をメソッドのシグネチャで宣言する必要があるだけではなく) 「出る」。 –

+1

申し訳ありませんが、私はそのあいまいさを取り除くために質問を改めました。 – GrandMasterFlush

1

C#では、これらのパラメータで何か異なることが起こり、渡された値が変更される可能性があることを警告/ポインターとしてとマークします。例えば、この場合には:

int myInt = 12; 
string myString = Fizz(myInt); 
// What is the value of myInt at this point? 

私はmyIntの値が12であることが、上記の例を見て知っているoutrefパラメータが暗黙的であれば、しかし、これはケースではありません。

1

あなたのコードを読んでいる人は、あなたがやっていることを知っているので、渡された変数が変更される可能性があることが明らかになります。

これは偶然にあなたを止めるという追加の利点があります。

暗黙のうちにrefを渡すプラットフォームでコードを管理していたとしても、デフォルトでは、3文字の入力は、明快さ(場合によっては正気)を支払うための小さな値段です。

関連する問題