📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
編集の要約なし |
|||
| (同じ利用者による、間の4版が非表示) | |||
| 19行目: | 19行目: | ||
デリゲートの作成において、C# 3.0で追加されたラムダ式を使用することで、匿名メソッドよりも簡潔に記述できる。<br> | デリゲートの作成において、C# 3.0で追加されたラムダ式を使用することで、匿名メソッドよりも簡潔に記述できる。<br> | ||
また、IEnumerable<T>を実装したクラスであればインスタンスメソッドとして記述できる。<br> | また、IEnumerable<T>を実装したクラスであればインスタンスメソッドとして記述できる。<br> | ||
< | <br> | ||
<syntaxhighlight lang="csharp"> | |||
// 匿名メソッド | // 匿名メソッド | ||
Func<string, bool> predicate = delegate (string str) | Func<string, bool> predicate = delegate (string str) | ||
| 34行目: | 35行目: | ||
// ラムダ式を更に短く記述 | // ラムダ式を更に短く記述 | ||
Func<string, bool> predicate = str => str.Length < 5; | Func<string, bool> predicate = str => str.Length < 5; | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
< | ==== Action ==== | ||
Actionは、パラメータを受け取り、戻り値を返さないデリゲート (メソッドを参照する型) である。<Br> | |||
戻り値がない (voidを返す) メソッドを表現する場合に使用する。<br> | |||
<br> | |||
引数は0〜16個までのパラメータを受け取ることが可能である。<br> | |||
コンソール出力やデータの保存等の処理に使用されることが多い。<br> | |||
<br> | |||
マルチスレッドでGUIを処理する場合にも、invokeメソッドと同時に使用することがある。<br> | |||
詳細は、[[C_Sharpの基礎_-_マルチスレッドとGUI#Invokeメソッドを使う]]を参照すること。<br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
// Actionの基本 | |||
Action sayHello = () => Console.WriteLine("Hello, Action"); | |||
sayHello(); // 出力: Hello, Action | |||
// 引数が1つのAction | |||
Action<string> greet = (name) => Console.WriteLine($"Hello, {name}!"); | |||
greet("John"); // 出力: Hello, John! | |||
// 引数を2つのAction | |||
Action<int, int> printSum = (x, y) => Console.WriteLine($"Sum: {x + y}"); | |||
printSum(5, 3); // 出力: Sum: 8 | |||
// コレクション処理 (リストの各要素を2倍にする) | |||
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; | |||
Action<int> twiceNumber = (n) => Console.WriteLine($"Number: {n * 2}"); | |||
numbers.ForEach(twiceNumber); | |||
// イベントハンドリング | |||
Action<string> logMessage = (message) => Console.WriteLine($"Log: {message}"); | |||
// メソッドの引数にする | |||
void ProcessItems<T>(IEnumerable<T> items, Action<T> processor) | |||
{ | { | ||
var | foreach (var item in items) | ||
{ | { | ||
" | processor(item); | ||
} | |||
} | |||
}; | </syntaxhighlight> | ||
<br> | |||
また、Actionを使用してラムダ式の即時実行を行うこともできる。<br> | |||
<syntaxhighlight lang="c#"> | |||
// 括弧を使用した即時実行 | |||
new Action<int>(x => | |||
{ | |||
x++; | |||
})(1); | |||
int | // Invokeメソッドを使用した即時実行 | ||
new Action<int>(x => | |||
{ | |||
x++; | |||
}).Invoke(1); | |||
// ローカル変数を使用・変更する場合 | |||
int result = 1; | |||
new Action<int>(x => | |||
{ | |||
result = x + 1; | |||
Console.WriteLine($"値 : {result}"); | |||
})(1); | |||
</syntaxhighlight> | |||
<br> | |||
==== Func ==== | |||
Funcとは、パラメータを受け取り、値を返すデリゲートである。<br> | |||
最後の型パラメータが戻り値の型を表す。<br> | |||
<br> | |||
0〜16個までの入力パラメータを受け取ることができる。<br> | |||
<br> | |||
Funcは、値の変換や計算処理によく使用されている。<br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
// Funcの基本 | |||
Func<int> getRandomNumber = () => new Random().Next(1, 100); | |||
int random = getRandomNumber(); // 1〜100までのランダムな数値を取得 | |||
// 引数を1つ受け取り、戻り値を返すFunc | |||
Func<int, bool> isEven = (number) => number % 2 == 0; | |||
bool result = isEven(4); // true | |||
// 引数が2つでdouble型の戻り値を返すFunc | |||
Func<int, int, double> calculateAverage = (x, y) => (x + y) / 2.0; | |||
double average = calculateAverage(10, 15); // 12.5 | |||
// コレクション処理 (リストの要素を変換) | |||
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; | |||
Func<int, string> numberToString = (n) => $"Value: {n}"; | |||
List<string> stringNumbers = numbers.Select(numberToString).ToList(); | |||
// 条件付き処理 | |||
Func<int, string> gradeScore = (score) => { | |||
if (score >= 90) return "A"; | |||
if (score >= 80) return "B"; | |||
if (score >= 70) return "C"; | |||
if (score >= 60) return "D"; | |||
return "F"; | |||
}; | |||
int studentScore = 85; | |||
string grade = gradeScore(studentScore); // "B" | |||
// 引数にFuncを渡す | |||
public static T TransformData<T>(string input, Func<string, T> transformer) | |||
{ | |||
return transformer(input); | |||
} | } | ||
</ | </syntaxhighlight> | ||
<br> | |||
==== コレクション処理 ==== | |||
<syntaxhighlight lang="csharp"> | |||
var names = new List<string> | |||
{ | |||
"Taro", | |||
"Jiro", | |||
"Saburo" | |||
}; | |||
int count = CountList(names, str => str.Length < 5); | |||
</syntaxhighlight> | |||
<br> | |||
==== LINQとの連携 ==== | |||
LINQの各メソッドと組み合わせることにより、効率的なコレクション処理が可能である。<br> | |||
<br> | <br> | ||
以下の例では、LINQのCountメソッドを記述している。<br> | 以下の例では、LINQのCountメソッドを記述している。<br> | ||
<br> | |||
拡張メソッドであるCountメソッドは、IEnumerable<T>型の拡張メソッドであり、引数はFunc<TSource, bool>型である。<br> | |||
< | また、Countメソッドは、nullチェック等の処理も含まれている。<br> | ||
<syntaxhighlight lang="csharp"> | |||
int count = names.Count(str => str.Length < 5); | int count = names.Count(str => str.Length < 5); | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
また、拡張メソッドと型推論を知ることで、LINQをより理解することができる。<br> | また、拡張メソッドと型推論を知ることで、LINQをより理解することができる。<br> | ||
LINQの詳細は、[[LINQ - 拡張メソッド一覧|C_Sharpの基礎 - LINQ]]を参照すること。<br> | |||
<br> | <br> | ||
==== 式木データ ==== | ==== 式木データ ==== | ||
| 65行目: | 181行目: | ||
これに対して、ラムダ式を<code>Expression</code>型の変数に代入すると、式木データとして扱うことができ、<br> | これに対して、ラムダ式を<code>Expression</code>型の変数に代入すると、式木データとして扱うことができ、<br> | ||
以下のように、式中の項を取得するといった操作ができる。<br> | 以下のように、式中の項を取得するといった操作ができる。<br> | ||
< | <syntaxhighlight lang="csharp"> | ||
Expression<Func<int, bool>> e = n => n > 0; | Expression<Func<int, bool>> e = n => n > 0; | ||
BinaryExpression lt = (BinaryExpression)e.Body; | BinaryExpression lt = (BinaryExpression)e.Body; | ||
ParameterExpression en = (ParameterExpression)lt.Left; | ParameterExpression en = (ParameterExpression)lt.Left; | ||
ConstantExpression zero = (ConstantExpression)lt.Right; | ConstantExpression zero = (ConstantExpression)lt.Right; | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
インタプリタ型の関数型言語には、匿名関数と式木データを区別しないものがあり、ある時はラムダ式を匿名関数として、またある時は式木データとして使用することができる。<br> | インタプリタ型の関数型言語には、匿名関数と式木データを区別しないものがあり、ある時はラムダ式を匿名関数として、またある時は式木データとして使用することができる。<br> | ||
| 81行目: | 197行目: | ||
<br> | <br> | ||
以下の例では、1つ目のラムダ式はコンパイル可能であるが、2つ目はコンパイルエラーになる。<br> | 以下の例では、1つ目のラムダ式はコンパイル可能であるが、2つ目はコンパイルエラーになる。<br> | ||
< | <syntaxhighlight lang="csharp"> | ||
// コンパイル可能 | // コンパイル可能 | ||
Expression<Func<int, bool>> p = n => n > 0; | Expression<Func<int, bool>> p = n => n > 0; | ||
| 93行目: | 209行目: | ||
return sum * prod; | return sum * prod; | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
また、LINQ to SQLでは、ラムダ式の式木データを使用して、LINQクエリ式の条件式等を式木データとして取得し、<br> | また、LINQ to SQLでは、ラムダ式の式木データを使用して、LINQクエリ式の条件式等を式木データとして取得し、<br> | ||
| 102行目: | 218行目: | ||
<br> | <br> | ||
これは、<code>c.City == "London"</code>の部分を式木データとして取得して、その内容を見ながらSQL文を生成している。<br> | これは、<code>c.City == "London"</code>の部分を式木データとして取得して、その内容を見ながらSQL文を生成している。<br> | ||
< | <syntaxhighlight lang="csharp"> | ||
// LINQクエリ式 | // LINQクエリ式 | ||
var q = from c in db | var q = from c in db | ||
| 118行目: | 234行目: | ||
FROM [Customers] AS [t0] | FROM [Customers] AS [t0] | ||
WHERE [t0].[City] = @p0 | WHERE [t0].[City] = @p0 | ||
</ | </syntaxhighlight> | ||
<br><br> | |||
== デフォルト引数 == | |||
C# 12以降、ラムダ式の引数に既定値を与えることができる。<br> | |||
<syntaxhighlight lang="c#"> | |||
// 既定値の指定 | |||
var fn = (int x = 10) => 1; | |||
</syntaxhighlight> | |||
<br> | |||
また、params引数も使用することができる。<br> | |||
<syntaxhighlight lang="c#"> | |||
// params引数 | |||
var fn = (params int[] y) => 1; | |||
</syntaxhighlight> | |||
<br> | |||
既定値とparams引数も同時に使用することができる。<br> | |||
<syntaxhighlight lang="c#"> | |||
var fn = (int x = 1, params int[] y) => 1; | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] | ||