C#8.0 本質主義 第 5 章 – メソッドとパラメータ
5.1 メソッド呼び出し
5.1.1 名前空間
名前空間は主に、タイプを見つけて理解できるように、機能分野ごとにタイプを整理するために使用されます。さらに、名前空間は型名の競合を防ぐのに役立ちます。
5.1.2型名
5.1.3 範囲
5.1.4 メソッド名
5.1.5 仮パラメータと実パラメータ
5.1.6 メソッドの戻り値
5.1.7 ステートメントとメソッド呼び出しの比較
5.2 メソッド宣言
C# はグローバル メソッドをサポートしていないため、すべてを型宣言に含める必要があります。Main メソッドが静的とマークされているのはまさにこのためです。
5.2.1 パラメータの宣言
5.2.2 メソッドの戻り値の型宣言
メソッドが型を返す場合、その本体には「到達不能なエンドポイント」があってはなりません。つまり、中括弧にヒットした後、値を返さずにメソッドを自然に終了することはできません。
C# 7.0 以降では、タプル構文を使用して複数の値をタプルにパックして返すことができます。
5.2.3 式本体メソッド
メソッドの定義を簡素化するために、C# 6.0 では式 body Methodが導入されました。これにより、完全なメソッド本体の代わりに式を使用できるようになります。
C++ とは異なり、C# クラスは実装を宣言から分離することはありません (C# は、メソッドの宣言と実装を分離できる「部分メソッド」と呼ばれる高度な機能をサポートしています)。
static string GetFullName( string firstName, string lastName) =>
$"{ firstName } { lastName }";
5.3ディレクティブの使用
using ディレクティブは、ネストされた名前空間の型を "インポート" しません。using System; が追加されていますが、System.Text の StringBuilder 型にアクセスするには、using System.Text ディレクティブを追加するか、型を完全修飾する必要があります。
Java では、ワイルドカードを使用して名前空間をインポートできますが、C# ではそれが許可されていないため、各名前空間を明示的にインポートする必要があります。
5.3.1静的ディレクティブの使用
5.3.2 エイリアスの使用
using ディレクティブを使用して、名前空間または型に別名を付けることができます。エイリアスの最も一般的な 2 つの使用法は、同じ名前を持つ 2 つの型を明確にすることと、長い名前を省略することです。
5.4Main()の戻り値とパラメータ
C# では、プログラムの実行時にコマンド ライン引数の指定がサポートされており、Main() メソッドからステータス識別子を返すことができます。
5.5 高度なメソッドパラメータ
5.5.1 値パラメータ
デフォルトでは、パラメータは値によって渡されます。
int a=123;
string b="456";
ClassC c=new ClassC();
func(a,b,c);
func(int a,string b,ClassC c)
{
...
}
上記の呼び出しでは、a は値 123 を渡し、b は文字列リテラル値「456」を渡し、c は変数 c の値である c が指すオブジェクトの参照 (アドレス) を渡します。
これらの値は関数に渡され、関数内の a、b、c に代入されるため、関数内の abc は新しく作成されたローカル変数になります。c のメンバーに値を割り当てると、c はすべて同じオブジェクトを指すため、外側の c に影響します。しかし、c 変数 new に新しいオブジェクトを与えても、c はローカル変数であるため、外部の c には影響しません。文字列についても同様です。
5.5.2 参照パラメータ
呼び出し元は、参照によって渡されたローカル変数を初期化する必要があります。
関数の ref パラメータは、渡される変数の単なるエイリアスです。つまり、参照パラメータの機能は、新しい変数を作成して実際の変数の値をコピーするのではなく、既存の変数にパラメータ名を割り当てることだけです。それにパラメータを設定します。
5.5.3 出力パラメータ
out パラメーターの機能は ref パラメーターの機能とまったく同じですが、C# 言語ではエイリアス変数の読み取りと書き込みに関する規定が異なることが異なります。パラメーターがマークアウトされている場合、コンパイラーは、通常メソッドから返されるすべてのコード パスでパラメーターに値が割り当てられているかどうかを確認します。
C# 7.0 以降では、使用前に out 変数を宣言するのではなく、メソッドを呼び出す前に out 変数をインラインで宣言できるようになりました。
C# 7.0 のもう 1 つの機能は、パラメーターを完全に破棄できることです。パラメーターはアンダースコアを使用して破棄できます。
TryGetPhoneButton(character,out _);
C# 7.0 でコードを記述する場合は、2 つ以上の値を返すためにタプル構文を優先する必要があります。
5.5.4 読み取り専用参照
C#7.2 は、読み取り専用の値型の参照による受け渡しをサポートしています。これにより、メソッドが呼び出されるたびに値型のコピーが作成されることがなくなり、値型パラメータが変更されることを心配する必要がなくなります。つまり、値を渡す際のコピー量を減らし、パラメータに in 修飾子を追加する機能です。
5.5.5 リターンリファレンス
C# 7.0 のもう 1 つの新機能は、変数への参照を返すことです。
// Returning a reference
public static ref byte FindFirstRedEyePixel(byte[] image)
{
// Do fancy image detection perhaps with machine learning
for (int counter = 0; counter < image.Length; counter++)
{
if (image[counter] == (byte)ConsoleColor.Red)
{
return ref image[counter];
}
}
throw new InvalidOperationException("No pixels are red.");
}
public static void Main()
{
byte[] image = new byte[254];
// Load image
int index = new Random().Next(0, image.Length - 1);
image[index] =
(byte)ConsoleColor.Red;
Console.WriteLine(
$"image[{index}]={(ConsoleColor)image[index]}");
// ...
// Obtain a reference to the first red pixel
ref byte redPixel = ref FindFirstRedEyePixel(image);
// Update it to be Black
redPixel = (byte)ConsoleColor.Black;
Console.WriteLine(
$"image[{index}]={(ConsoleColor)image[redPixel]}");
}
ref ローカル変数は特定の変数を参照するように初期化され、後で他の変数を参照するように変更することはできません。(C++ での引用に少し似ています)
5.5.6 パラメータ配列
カンマ区切りの文字列パラメータまたは単一の文字列配列。パラメータ配列が宣言された後、各パラメータはパラメータ配列のメンバーとしてアクセスされます。
パラメータ配列は最後のものである必要があるため、1 つだけ存在できます。
5.6 再帰
5.7 メソッドのオーバーロード
メソッドのオーバーロードは、操作上の多態性の一種です。ポリモーフィズムは、データの変更により同じ論理演算が多数の形式を持つ場合に発生します。
5.8 オプションのパラメータ
C# 4.0 では、オプションのパラメーターのサポートが追加されています。オプションのパラメータは、すべての必須パラメータの後に配置する必要があります。デフォルト値は、コンパイル時に決定できる定数またはその他の値である必要があります。
C# 4.0 のもう 1 つの新しいメソッド呼び出し機能は、parameters という名前です。
public static void Main()
{
DisplayGreeting(
firstName: "Inigo", lastName: "Montoya");
}
public static void DisplayGreeting(
string firstName,
string? middleName = null,
string? lastName = null
)
{
// ...
}
メソッドに多数のパラメーター (その多くはオプション) がある場合、名前付きパラメーター構文は間違いなく大量のトラバーサルを引き起こしますが、メソッド インターフェイスの柔軟性が犠牲になり、パラメーター名はメソッドインターフェイス。
いずれかのメソッドにオプションのパラメーターがあるために両方のメソッドが適用できる場合、コンパイラーは最終的にオプションのパラメーターのないメソッドを選択します。