ホームページ  >  記事  >  バックエンド開発  >  C# での ref、out、in キーワードの使用法は何ですか?

C# での ref、out、in キーワードの使用法は何ですか?

WBOY
WBOY転載
2023-09-18 12:45:03779ブラウズ

C# 中 ref、out 和 in 关键字的用法是什么?

C# では、ほとんどのメソッドは 0 個以上のパラメーターを持つことができ、メソッドに提供する必要があるデータを定義します。メソッドを呼び出すコードはすべて、データ (パラメーターと呼ばれる) をメソッドに渡す必要があります。メソッドは入力をパラメータとして宣言し、それらは呼び出しコードによってパラメータとして提供されます。

たとえば、次のメソッドと後続のメソッド呼び出しについて考えてみましょう。

static void Greet(string greeting){
   Console.WriteLine(greeting);
}
...
Greet("Hello");

上記の例では、greeting は Greet() メソッドのパラメータであり、「Hello」はメソッドに渡されるパラメータです。

メソッドを呼び出して引数を渡す場合、それらは値によって渡されます。つまり、メソッドに渡されるときに値のコピーが作成されます。メソッド内のパラメーターに加えられた変更は、元の変数には反映されません。

using System;
int number = 8;
Increase(number);
Console.WriteLine(number); // prints 8
static void Increase(int num){
   num = num + 1;
   Console.WriteLine(num); // prints 9
}

参照型変数 (オブジェクトなど) を渡す場合、変数には実際のオブジェクトではなく参照が保持されるため、C# は引き続き reference を値でコピーします。したがって、参照変数のコピーを渡しても、それらはすべてメモリ内の同じオブジェクトを参照します。したがって、メソッド内の変数によってオブジェクトに加えられた変更は、メソッドの外部の変数からも認識されます。

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(john);
Console.WriteLine(john.Salary); // prints 60000
static void Promote(User u){
   u.Salary += 10000;
   Console.WriteLine(u.Salary); // prints 60000
}

ただし、メソッド内で変数自体の値を変更した場合、実際のオブジェクトではなくコピーのみが変更されるため、変更はメソッドの外部には反映されません。たとえば、メソッド内でパラメータを null に割り当てることができますが、実際の変数は変更されません。

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(john);
Console.WriteLine(john.Salary); // prints 50000
static void Promote(User u){
   u = null;
}

C# では、3 つの異なる修飾子キーワードを使用してメソッドのパラメーターを制御できます。

ref 修飾子

C# では、ref 修飾子を使用してパラメータを参照によって渡すことができます。渡される変数が参照型であるか値型であるかは関係ありません。引数と引数は同じメモリ位置を参照します。

次の例では、パラメータ u を null に設定すると、john 変数も null になるため、null 参照例外がスローされます。

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(ref john);
Console.WriteLine(john.Salary); // throws System.NullReferenceException
static void Promote(ref User u){
   u = null;
}

ref 修飾子を使用して渡されるパラメータは、渡す前に初期化する必要があります。

out 修飾子

これは ref 修飾子と似ていますが、次の点が異なります。

  • 関数に入る前にパラメータを初期化する必要はありません

  • 関数を終了する前にパラメータを初期化 (割り当て) する必要があります。

以下の例では、Hire 関数は、経由で渡された関数を初期化します。 out 修飾子の新しいユーザー オブジェクト。変数 john は、Hire メソッドが呼び出されたときにオンザフライで宣言されることに注意してください。

using System;
Hire(out User john);
Console.WriteLine(john.Salary); // prints 50000
static void Hire(out User u){
   u = new User{
      Name = "John",
      Salary = 50000
   };
}

ref 修飾子と同様、out 修飾子でマークされた変数は参照によって渡されます。

通常、 out > 変数は、次のように関数から複数の戻り値を取得するために使用されます -

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
bool shouldPromote = Raise(john.Salary, out double hike);
Console.WriteLine(shouldPromote); // True
Console.WriteLine($"Hike Amount = {hike}"); // prints 5000
static bool Raise(int salary, out double hike){
   hike = salary * 0.1;
   return hike < 7000;
}

in 修飾子

これは次のようになります。 ref パラメータと out パラメータは同じですが、in パラメータを受け入れるメソッドはパラメータの値を変更できないという点が異なります。変更を試みると、C# コンパイラはコンパイル時エラーを生成します。

inParameters を使用すると、大きな値型のメモリをパラメータ変数にコピーすることを回避し、オブジェクトが誤って変更されるのを防ぐことができます。これは、大きな値の型をメソッドに渡すときに便利です。

var point = new Coord();
Verify(point);
static void Verify(in Coord c){
   // error: Cannot assign to variable &#39;in Coord&#39; because it is a readonly variable
   c = new Coord();
}
struct Coord{
   public int X;
   public int Y;
}

リアルタイム デモンストレーション

using System;
class Program{
   static void Main(){
      int number = 8;
      Increase(number);
      Console.WriteLine(number); // prints 8
      var john = new User { Name = "John", Salary = 50000 };
      Promote(john);
      Console.WriteLine(john.Salary); // prints 60000
      Leave(john);
      Console.WriteLine(john.Salary); // prints 60000

      LeaveByRef(ref john);
      Console.WriteLine(john?.Salary); // prints nothing

      User dave;
      Hire(out dave);
      Console.WriteLine(dave.Salary); // prints 50000
   }
   static void Increase(int num){
      num = num + 1;
      Console.WriteLine(num); // prints 9
   }
   static void Promote(User u){
      u.Salary += 10000;
      Console.WriteLine(u.Salary); // prints 60000
   }
   static void Leave(User u){
      u = null;
   }
   static void LeaveByRef(ref User u){
      u = null;
   }
   static void Hire(out User u){
      u = new User{
         Name = "John",
         Salary = 50000
      };  
   }
}
class User{
   public string Name { get; set; }
   public int Salary { get; set; }
}

出力

9
8
60000
60000
60000
50000

以上がC# での ref、out、in キーワードの使用法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はtutorialspoint.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。