この質問にはすでに答えがあります。
違いは何ですかref
そしてout
.NETでパラメータ?一方がもう一方よりも役立つ可能性がある状況は何ですか? 1つを使用でき、もう1つを使用できないコードスニペットは何でしょうか。
それらはほとんど同じです - 唯一の違いはあなたが変数として渡す変数です。out
パラメータは初期化する必要はありませんが、ref
パラメータそれは何かに設定する必要があります。
int x;
Foo(out x); // OK
int y;
Foo(ref y); // Error: y should be initialized before calling the method
Ref
パラメータは変更される可能性のあるデータ用です。out
パラメータは関数の追加出力であるデータ用です(例:int.TryParse
)すでに返り値を使っています。
outパラメータを受け取るメソッドの呼び出し元は、呼び出しの前にoutパラメータとして渡された変数に割り当てる必要はありません。ただし、呼び出し先は戻る前にoutパラメーターに割り当てる必要があります。
対照的に、refパラメータは呼び出し元によって最初に割り当てられたと見なされます。そのため、呼び出し先は使用前にrefパラメータに割り当てる必要はありません。参照パラメータは、メソッドの内外に渡されます。
そう、out
を意味しますref
出入り用です。
これらは密接に対応します[out]
そして[in,out]
COMインターフェイスのパラメータ、out
呼び出し側のメソッドが不要な場合は、呼び出し側が事前割り当て済みオブジェクトを渡す必要がないというパラメータです。これにより、割り当てのコストと、マーシャリングに関連する可能性があるコストの両方が回避されます。 .NETでは一般的ではありません。
ref
そしてout
両方とも呼び出されたメソッドがパラメータを変更することを可能にします。それらの違いは何が起こるかです前あなたは電話をかけます。
ref
パラメータに値があることを意味します前機能に入る。呼び出された関数はいつでも値を読み込んだり変更したりできます。パラメータが入ってから出てくる
out
関数に入る前にパラメータは公式の値を持たないことを意味します。呼び出された関数はそれを初期化しなければなりません。パラメータは消えるだけです
これを見るための私のお気に入りの方法は次のとおりです。ref
参照によって変数を渡すことです。out
セカンダリを宣言することです戻り値機能のため。あなたがこれを書くことができるかのようです:
// This is not C#
public (bool, string) GetWebThing(string name, ref Buffer paramBuffer);
// This is C#
public bool GetWebThing(string name, ref Buffer paramBuffer, out string actualUrl);
これが各選択肢の効果のより詳細なリストです。
ref
:呼び出し側は、呼び出されたメソッドに渡す前にパラメータの値を設定しなければなりません。
out
呼び出し元のメソッドは、メソッドを呼び出す前に引数の値を設定する必要はありません。たぶん、そうすべきではありません。実際、現在の値はすべて破棄されます。
ref
:呼び出されたメソッドはいつでも引数を読み取ることができます。
out
:呼び出されたメソッドはパラメータを読み込む前に初期化する必要があります。
ref
:現在の値がリモートコールに整列化されます。追加のパフォーマンスコスト
out
:リモートコールには何も渡されません。もっと早く。
技術的に言えば、いつでも使用できますref
代わりにout
しかし、out
引数の意味についてより正確になることを可能にし、時にはそれがはるかに効率的になることがあります。
OUTの例:変数は、メソッドに入ると値が初期化されます。後で同じ値がmainメソッドに返されます。
namespace outreftry
{
class outref
{
static void Main(string[] args)
{
yyy a = new yyy(); ;
// u can try giving int i=100 but is useless as that value is not passed into
// the method. Only variable goes into the method and gets changed its
// value and comes out.
int i;
a.abc(out i);
System.Console.WriteLine(i);
}
}
class yyy
{
public void abc(out int i)
{
i = 10;
}
}
}
出力:
10年
=================================================
Refの例:変数はメソッドに入る前に初期化されるべきです。後で同じ値または変更された値がmainメソッドに返されます。
namespace outreftry
{
class outref
{
static void Main(string[] args)
{
yyy a = new yyy(); ;
int i = 0;
a.abc(ref i);
System.Console.WriteLine(i);
}
}
class yyy
{
public void abc(ref int i)
{
System.Console.WriteLine(i);
i = 10;
}
}
}
出力:
0 10
================================
今はっきりしていることを願っています。
ref
変数は渡す前に初期化する必要があります。out
変数はあなたの関数実装で設定される必要がありますout
パラメーターは追加の戻り変数(入力ではない)と見なすことができます。ref
パラメータは入力変数と出力変数の両方として考えることができます。
のout
そしてそのref
パラメータは、メソッドの引数として渡すのと同じ変数に値を返すために使用されます。メソッドが複数の値を返す必要がある場合、これら両方のパラメータは非常に便利です。
caleeメソッド本体のoutパラメータに値を代入する必要があります。そうしないと、メソッドはコンパイルされません。
参照パラメータ:メソッドに渡す前に初期化する必要があります。 の
ref
メソッドパラメータのkeywordは、同じメソッドの入力パラメータとして渡されたものと同じ変数をメソッドが参照するようにします。変数に何らかの変更を加えると、それらは変数に反映されます。int sampleData = 0; sampleMethod(ref sampleData);
RefパラメータのEx
public static void Main()
{
int i = 3; // Variable need to be initialized
sampleMethod(ref i );
}
public static void sampleMethod(ref int sampleData)
{
sampleData++;
}
出力パラメータ:Methodに渡す前に初期化する必要はありません。 の
out
parameterは、メソッドのパラメータとして渡されたのと同じ変数内の値を返すために使用できます。パラメータに加えられた変更はすべて変数に反映されます。int sampleData; sampleMethod(out sampleData);
OutパラメータのEx
public static void Main()
{
int i, j; // Variable need not be initialized
sampleMethod(out i, out j);
}
public static int sampleMethod(out int sampleData1, out int sampleData2)
{
sampleData1 = 10;
sampleData2 = 20;
return 0;
}
C#では、メソッドは1つの値しか返すことができません。複数の値を返したい場合は、outキーワードを使用できます。 out修飾子は参照による戻り値として返します。最も単純な答えは、メソッドから値を取得するためにキーワード「out」が使用されることです。
C#では、int、float、doubleなどの値型をメソッドパラメータの引数として渡すと、値によって渡されます。したがって、パラメータ値を変更しても、メソッド呼び出しの引数には影響しません。しかし、もしあなたが“ ref”キーワードでパラメータをマークすると、それは実際の変数に反映されます。
refパラメータは関数内で設定する必要はありませんが、outパラメータは関数を終了する前に値にバインドする必要があります。 outとして渡された変数は、初期化されずに関数に渡されることもあります。
out
パラメータが出力パラメータであること、つまりメソッドによって明示的に設定されるまで値がないことを指定します。
ref
値が値を持ち、その値をメソッド内で変更できる参照であることを指定します。
out
パラメータは、呼び出されたメソッドによって初期化されます。ref
メソッドを呼び出す前にパラメータが初期化されます。したがって、out
二次戻り値を取得するだけの場合は、パラメータが使用されます。ref
パラメータは値を取得するために使用されますそして潜在的にその値への変更を返します(2番目に主な戻り値へ)。
refキーワードは、参照によって値を渡すために使用されます。 (これは、渡された値が値型または参照型であることを排除するものではありません)。 outキーワードで指定された出力パラメータは、メソッドから値を返すためのものです。
コードの大きな違いの1つは、メソッド内で出力パラメータの値を設定する必要があるということです。これは、refパラメータには当てはまりません。
詳細については見てくださいhttp://www.blackwasp.co.uk/CSharpMethodParameters.aspx
あout
パラメータはref
特別なパラメータOut()
属性が追加されました。 C#メソッドへのパラメータが次のように宣言されている場合out
コンパイラは、パラメータが読み取られる前、およびメソッドが戻る前に、パラメータを書き込むことを要求します。 C#がパラメータを含むメソッドを呼び出す場合Out()
attributeを指定した場合、コンパイラは、 "未定義の変数"エラーを報告するかどうかを決定するために、メソッドを呼び出す直前に変数が書き込まれるように見せかけるでしょう。他の.net言語が同じ意味を添付していないので注意してください。Out()
属性を使ってルーチンを呼び出すことは可能です。out
パラメータは問題の変数に影響を与えません。変数が変数として使用されている場合out
確実に代入される前にC#コンパイラが使用される前のある時点で確実にクリアされるようにC#コンパイラはコードを生成しますが、そのような変数がスコープを離れて再び入ると、再度クリアされる保証はありません。
refはおそらく既存のオブジェクトを修正することを期待しているので、refはおそらくnullをチョークするでしょう。新しいオブジェクトを返すのでoutはnullを期待します。
outとrefは、out変数を深淵に送信する前に初期化する必要がないことを除いて、まったく同じです。私はそんなに賢くはありません、私はそれをMSDNのライブラリから切り取った:)。
しかし、それらの使用についてより明確にするために、修飾子の意味は、あなたがコードの中でその変数の参照を変更した場合、outとrefはあなたの呼び出し側の変数も参照を変更するということです。以下のコードでは、ceSt変数は、doStuffの呼び出しから戻った後のnewGuyへの参照になります。それがref(またはout)用でなければ、参照は変更されません。
private void newEmployee()
{
Person ceo = Person.FindCEO();
doStuff(ref ceo);
}
private void doStuff(ref Person employee)
{
Person newGuy = new Person();
employee = newGuy;
}
微妙に違います。
あout
parameterは、メソッドに渡される前に呼び出し先によって初期化される必要はありません。したがって、out
パラメータ
これは、前の値に関係なく引数を上書きする必要があるメソッドに使用されます。
Aref
parameterはメソッドに渡す前に呼び出し先によって初期化されなければなりません。したがって、ref
パラメータ
これは、(例えば)その値を調べてそれを検証するかまたは正規化しなければならない方法に使用される。
outはC#7でさらに簡潔な構文を得ましたhttps://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-membersさらにもっと刺激的なのは、C#7タプルの機能強化です。これは、refを使用してIMHOを使用するよりも優雅な選択です。
out
パラメータは初期化する必要があります。を受け取るメソッドref
パラメータはそれが望むことをすることができます。それはきっとそれを無視することができます。ロールバックしています。 - xanatos