22

明確で簡潔で正確な答えを探しています。

良い説明へのリンクを歓迎しますが、理想的には実際の答えとして。

これはVB.Netにも当てはまりますが、キーワードは異なります-ByRefByVal

4

4 に答える 4

27

デフォルト(C#)では、オブジェクトを関数に渡すと、実際にはそのオブジェクトへの参照のコピーが渡されます。パラメーター自体を変更すると、パラメーターの値のみが変更され、指定された変数は変更されません。

void Test1(string param)
{
    param = "new value";
}

string s1 = "initial value";
Test1(s1);
// s1 == "initial value"

関数の呼び出しで指定された変数への参照を使用outまたはref渡します。outまたはパラメータの値への変更はref、呼び出し元に返されます。

outとはref、わずかな違いを除いて同じように動作します。refパラメータは呼び出す前に初期化する必要がありますが、outパラメータは初期化しない場合があります。拡張により、refパラメータはメソッドの開始時に初期化されることが保証されますが、パラメータは初期化outされていないものとして扱われます。

void Test2(ref string param)
{
    param = "new value";
}

void Test3(out string param)
{
    // Use of param here will not compile
    param = "another value";
}

string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"

編集dpoutが指摘しているように、との違いrefはC#コンパイラによってのみ強制され、CLRによっては強制されません。私の知る限り、VBには、CLRのサポートに一致する、(as )に相当するものはなくout、実装するだけです。refByRef

于 2008-08-16T12:06:17.337 に答える
8

refとoutに関するもう1つの注意事項:この2つの違いは、C#コンパイラによって強制されます。CLRは、outとrefを区別しません。これは、署名がoutまたはrefによってのみ異なる2つのメソッドを持つことができないことを意味します

void foo(int value) {}

// Only one of the following would be allowed

// valid to overload with ref
void foo(ref int value) {}

// OR with out
void foo(out int value) {}
于 2008-08-16T12:32:38.983 に答える
3

outパラメータが次のメソッドによって初期化されることを意味します。

int result; //not initialised

if( int.TryParse( "123", out result ) )
   //result is now 123
else
   //if TryParse failed result has still be 
   // initialised to its default value (0)

ref基になる参照が強制的に渡されます。

void ChangeMyClass1( MyClass input ) {
   input.MyProperty = "changed by 1";
   input = null;
   //can't see input anymore ... 
   // I've only nulled my local scope's reference
}

void ChangeMyClass2( ref MyClass input ) {
   input.MyProperty = "changed by 2";
   input = null;
   //the passed reference is now null too.
}

MyClass tester = new MyClass { MyProperty = "initial value" };

ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"

ChangeMyClass2( ref tester );
// now tester is null
于 2008-08-16T08:49:21.760 に答える
2

stackoverflowでの私自身の質問の1つは、このトピックも処理します。さまざまな種類の言語での「参照渡し」と「値渡し」
について処理します。c#が含まれているので、そこにもいくつかの追加情報があります。

基本的にそれは次のようになります。

  • ref:refキーワードを持つパラメーターは参照によって渡されます
  • out:outキーワードを持つパラメーターは、出力パラメーターとして扱われます

しかし、それはここで述べられているよりも少し複雑なので、あなたが与えることができる最も基本的な答えです

于 2008-08-16T09:21:35.563 に答える