1.方法
1. メソッドの定義
特定の操作を実行したり、結果を計算したりするための一連のステートメントで構成されます。メソッドは常にクラスに関連付けられており、タイプは関連するメソッドをグループ化します。
- メソッド名
- 仮パラメータと実パラメータ(パラメータ&引数)
- 戻り値
2. 名前空間
機能的に関連するすべてのタイプを組み合わせるための分類メカニズム。名前空間は階層構造になっており、レベルの数は任意です。名前空間の階層は通常、会社名で始まり、次に製品名、最後に機能分野になります。次に例を示します。
- Microsoft.Win32.ネットワーキング
主に、見つけやすく理解しやすいように機能分野ごとに整理するために使用されます。これに加えて、名前空間は型名の競合を防ぐのにも役立ちます。
3. 範囲
- 非修飾名で参照できる領域
- 型内のメソッドの呼び出しの場合、メソッドが型内で宣言されている場合、メソッドの呼び出しで型修飾子を使用する必要はありません。同様に、型はスコープ内でその名前空間全体を宣言します。
2. 表現
1. 式サブジェクトメンバー
式本体のメンバーは、よりクリーンで読みやすいメンバーの実装を提供します。
メンバー | 現在サポートされています... |
方法 | C#6 |
コンストラクタ | C#7 |
ファイナライザー | C#7 |
プロパティの取得 | C#6 |
プロパティセット | C#7 |
インデクサ | C#7 |
構文: メンバー => 式
2. 式本体メソッド
式本体メソッドは、矢印演算子 (=>) を使用して、ステートメント本体の代わりに単一の式をプロパティまたはメソッドに割り当てます。メソッドに戻り値がある場合、式の戻り値はメソッドの戻り値の型と同じである必要があります。メソッドに戻り値がない場合、式は一連の操作を実行します。
public class Person
{
public Person(string firstName, string lastName)
{
fname = firstName;
lname = lastName;
}
private string fname;
private string lname;
public override string ToString() => $"{fname} {lname}".Trim();
public void DisplayName() => Console.WriteLine(ToString());
}
3. メソッド宣言
C# はグローバル メソッドをサポートしていません。すべてのメソッドは型内に存在する必要があります。
public class Program
{
public static void ChapterMain()
{
string firstName, lastName, fullName, initials;
System.Console.WriteLine("Hey you!");
firstName = GetUserInput("Enter your first name: ");
lastName = GetUserInput("Enter your last name: ");
fullName = GetFullName(firstName, lastName);
initials = GetInitials(firstName, lastName);
DisplayGreeting(fullName, initials);
}
static string GetUserInput(string prompt)
{
System.Console.Write(prompt);
return System.Console.ReadLine();
}
static string GetFullName( string firstName, string lastName) => $"{ firstName } { lastName }";
static void DisplayGreeting(string fullName, string initials)
{
System.Console.WriteLine($"Hello { fullName }! Your initials are { initials }");
}
static string GetInitials(string firstName, string lastName)
{
return $"{ firstName[0] }. { lastName[0] }.";
}
}
4. Main()の戻り値とパラメータ
C# では、プログラムの実行時にコマンド ライン パラメーターを提供し、Main() メソッドからステータス識別子を返すことがサポートされています。Main() メソッド以外からコマンド ライン パラメーターにアクセスする必要がある場合は、System.Environment.GetcommandLineArgs() メソッドを使用できます。 :
public static int Main(string[] args)
{
int result;
string targetFileName, string url;
switch(args.Length)
{
default:
Console.WriteLine("ERROR: You must specify the "+ "URL and the file name"); // Exactly two arguments must be specified; give an error.
targetFileName = null;
url = null;
break;
case 2:
url = args[0];
targetFileName = args[1];
break;
}
if(targetFileName != null && url != null)
{
using (HttpClient httpClient = new HttpClient())
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url))
using (HttpResponseMessage message = httpClient.SendAsync(request).Result)
using (Stream contentStream = message.Content.ReadAsStreamAsync().Result)
using (FileStream fileStream = new FileStream(targetFileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
contentStream.CopyToAsync(fileStream);
}
return 0;
}
Console.WriteLine("Usage: Downloader.exe <URL> <TargetFileName>");
return 1;
}
5. メソッドのパラメータ
1. 値パラメータ
C# では、パラメーターの受け渡しはデフォルトで値渡しです。つまり、パラメーター式の値がターゲット パラメーターにコピーされます。
- 値型パラメータの場合、メソッドは値のコピーを取得するため、メソッド内で実際のパラメータの値を変更することはできません。
- 参照型パラメータの場合、メソッドは参照 (アドレス) のコピーを取得し、参照オブジェクトの値を変更できます。
public static void ChapterMain()
{
string fullName;
string driveLetter = "C:";
string folderPath = "Data";
string fileName = "index.html";
fullName = Combine(driveLetter, folderPath, fileName);
Console.WriteLine(fullName);
}
static string Combine(string driveLetter, string folderPath, string fileName)
{
string path;
path = string.Format("{1}{0}{2}{0}{3}", System.IO.Path.DirectorySeparatorChar, driveLetter, folderPath, fileName);
return path;
}
2. 参照パラメータ (ref)
- ref キーワードは、パラメータが値ではなく参照によって渡されることを示します。実パラメータが値型であっても参照型であっても参照渡し可能
- メソッド定義で ref キーワードを使用する場合、メソッドを呼び出すときに実際のパラメーターの前に ref 修飾を明示的に使用する必要があります。
- ref で修飾された実際のパラメータは、呼び出す前に初期化する必要があります
- 値型パラメーターの場合、参照渡しにより、メソッドで実際のパラメーターの値を変更できます。
class RefExample
{
static void Method(ref int i)
{
i = i + 44;
}
static void Main()
{
int val = 1;
Method(ref val);
Console.WriteLine(val); // Output: 45
}
}
- 参照型パラメーターの場合、参照渡しにより、メソッドは参照されるオブジェクトの値を変更するだけでなく、参照パラメーターによって参照されるオブジェクトを置き換えることもできます。
class RefExample2
{
static void Main()
{
Product item = new Product("Fasteners", 54321);// Declare an instance of Product and display its initial values.
System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
ChangeByReference(ref item); // Pass the product instance to ChangeByReference.
System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
}
static void ChangeByReference(ref Product itemRef)
{
// Change the address that is stored in the itemRef parameter.
itemRef = new Product("Stapler", 99999);
itemRef.ItemID = 12345;
}
}
class Product
{
public Product(string name, int newID)
{
ItemName = name;
ItemID = newID;
}
public string ItemName { get; set; }
public int ItemID { get; set; }
}
3. outパラメータ
- ref と同様に、out もパラメータが値ではなく参照によって渡されることを示します。メソッドが定義されるとき、仮パラメータは out を指定し、実パラメータも呼び出し時に out を使用して明示的に指定する必要があります。
- out と ref の違いは次のとおりです。
- out で修飾された引数は呼び出し前に初期化する必要はありません
- メソッドは戻る前にすべての out パラメーターに値を割り当てる必要があります。コンパイラーはすべてのリターン パスをチェックして、すべての out パラメーターに値が割り当てられていることを確認します。
- out は、メソッドから複数の値を返す必要がある場合によく使用されます。
class OutReturnExample
{
static void Method(out int i, out string s1, out string s2)
{
i = 44;
s1 = "I've been returned";
s2 = null;
}
static void Main()
{
int value;
string str1, str2;
Method(out value, out str1, out str2);
}
}
4.パラメータ配列(param)
C# では、メソッドのパラメーターの前に param を明示的に指定することで、メソッドを呼び出すときに可変数のパラメーターを指定できます。
- パラメータ配列はメソッドの唯一のパラメータである必要はありませんが、メソッドの最後のパラメータである必要があります。
- 実際のパラメータの型は、パラメータ配列内の要素の型と互換性がある必要があります。
- 呼び出し元は、カンマ区切りのパラメータを渡すか、明示的に配列を使用できます。
- 呼び出し元は、パラメーター配列に対応するゼロ引数を指定できます。
public static void ChapterMain()
{
string fullName;
fullName = Combine(Directory.GetCurrentDirectory(), "bin", "config", "index.html"); // Call Combine() with four parameters
Console.WriteLine(fullName);
fullName = Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Temp", "index.html"); // Call Combine() with only three parameters
Console.WriteLine(fullName);
fullName = Combine( new string[] {$"C:{Path.DirectorySeparatorChar}", "Data", "HomeDir", "index.html" }); // Call Combine() with an array
Console.WriteLine(fullName);
}
static string Combine(params string[] paths)
{
string result = string.Empty;
foreach (string path in paths)
result = System.IO.Path.Combine(result, path);
return result;
}
5. 名前付き引数
呼び出し元はパラメータに値を明示的に割り当てます。
- 呼び出し元はパラメータを任意の順序で指定できます
- 名前付きパラメータと通常のメソッドが混在している場合、名前付きパラメータはすべての通常パラメータの後に渡す必要があります。
static void Main(string[] args)
{
PrintOrderDetails("Gift Shop", 31, "Red Mug"); // The method can be called in the normal way, by using positional arguments.
// Named arguments can be supplied for the parameters in any order.
PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);
// Named arguments mixed with positional arguments are valid as long as they are used in their correct position.
PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
// However, mixed arguments are invalid if used out-of-order. The following statements will cause a compiler error.
// PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
// PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug");
// PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop");
}
static void PrintOrderDetails(string sellerName, int orderNum, string productName)
{
if (string.IsNullOrWhiteSpace(sellerName))
throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName: nameof(sellerName));
Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}");
}
6. オプションの引数
- メソッドを定義するときに、パラメーターがオプションであるかどうかを指定できます。メソッドの呼び出し時にオプション以外のパラメータをすべて指定する必要があり、オプションのパラメータは無視できます。
- 各オプションのパラメータには、次のタイプのいずれかのデフォルト値が必要です。
- 定数式
- 新しい valType の形式の式。valType は、struct や enum などの値の型です。
- default(valType) 形式の式。valType は値の型です。
- オプションのパラメータ タイプは、すべての非オプション パラメータの後に定義する必要があります。
- メソッドが呼び出されるとき、オプションのパラメーターに値が指定されている場合は、パラメーターの前のすべてのオプションのパラメーターで値を指定する必要がありますが、名前付きパラメーターを使用すると、この規則は無視できます。
オプションのパラメータの例:
static void Main(string[] args)
{
// Instance anExample does not send an argument for the constructor‘s optional parameter.
ExampleClass anExample = new ExampleClass();
anExample.ExampleMethod(1, "One", 1);
anExample.ExampleMethod(2, "Two");
anExample.ExampleMethod(3);
// Instance anotherExample sends an argument for the constructor‘s optional parameter.
ExampleClass anotherExample = new ExampleClass("Provided name");
anotherExample.ExampleMethod(1, "One", 1);
anotherExample.ExampleMethod(2, "Two");
anotherExample.ExampleMethod(3);
// You cannot leave a gap in the provided arguments.
//anExample.ExampleMethod(3, ,4);
//anExample.ExampleMethod(3, 4);
// You can use a named parameter to make the previous statement work.
anExample.ExampleMethod(3, optionalint: 4);
}
class ExampleClass
{
private string _name;
public ExampleClass(string name = "Default name")
{
_name = name;
}
public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)
{
Console.WriteLine("{0}: {1}, {2}, and {3}.", _name, required, optionalstr, optionalint);
}
}
6. メソッドのオーバーロード
C++ と同様に、C# もメソッドのオーバーロードをサポートします。C# はパラメーターの型とパラメーターの数に基づいて最も一致するメソッドを選択します
名前付きパラメーターとオプションのパラメーターはオーバーロード ルールに影響します
- 各引数がオプションであるか、引数の型に変換可能な名前または位置による引数が 1 つだけある場合、メソッドは候補になります。
- 複数の候補が見つかった場合、優先変換のオーバーロード ルールが明示的に指定された引数に適用されます。呼び出し元によって提供されないオプションのパラメーターは無視します。
- 2 つの候補が同等に一致する場合、デフォルト値を使用するオプションのパラメーターのない候補が優先されます。これは、オーバーロードの意思決定においてパラメータが少ない候補ルールが優先された結果です。