0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C# 超入門 丁寧に解説 デリゲート

Last updated at Posted at 2024-07-30

はじめに

現場でC#を使って開発をしています。デリゲートの使い方について一から学んだので備忘録として書いています。間違いがあればコメントお願いします。

デリゲートとは?

メソッドを参照するための型のこと。他のメソッドへの引数としてメソッドを渡すために使用される。
公式資料

実際に使ってみた

delegate bool LenCheck(string value); //①デリゲート宣言

private bool Shiki1(string value) //②メソッド実装
{
    return value.Length == 3;
}

 private string[] GetValue3(string[] values, LenCheck lenCheck) //③デリゲートを使用するメソッド
 {
     var result = new List<string>();
     foreach (var val in values)
     {
         if (lenCheck(val))
         {
             result.Add(val);
         };
     }

     return result.ToArray();
 }
 
 private void button1_Click(object sender, EventArgs e) //④メソッドの実行
 {
     var values = new string[] { "A", "BB", "CCC", "DDDD", "EEEEE" };
     var result = GetValue3(values, Shiki1);

     Console.WriteLine(string.Join(",", result));
 }

引用元:https://anderson02.com/cs/lambda/lambda07/

コードの解説

①デリゲート宣言

delegate   bool    LenCheck(string value);
delegate   戻り値   名前(型名)   引数

LenCheckという名前のデリゲート型を宣言。string型の引数を受け取り、bool型の戻り値を返すメソッドであることを示している。

②メソッド実装

private bool Shiki1(string value) 
{
    return value.Length == 3;
}

①で宣言したデリゲートと引数、戻り値を合わせる。なのでstring型の引数を受け取り、bool型を戻り値のメソッドを定義。

③デリゲートを使用するメソッド

private string[] GetValue3(string[] values, LenCheck lenCheck) 
 {
     var result = new List<string>();
     foreach (var val in values)
     {
         if (lenCheck(val))
         {
             result.Add(val);
         };
     }

     return result.ToArray();
 }

GetValue3メソッドがLenCheckデリゲートを引数として受け取る。つまり引数としてメソッドを渡されている。
この例では、引数としてlenCheck=Shiki1メソッドを受け取っている。
また、foreachで各要素に対してlenCheck(Shiki1)が呼び出し、value.Length == 3の場合はtrueを戻り値として返す。valがstring型以外になるとエラーとなる。

④メソッド実行
button1_Clickメソッドが実行されると、「CCC」がコンソール上に表示されます。

定義済みデリゲート

.NETの標準ライブラリに存在するデリゲート型のこと。
自分でデリゲートを定義する必要がなくなり、なにかと便利。
Predicate,Func,Actionがある。

Predicate型

1つ引数を受け取り、戻り値がbool型を返す

①引数としてPredicate pridicateをデリゲート宣言がいらない。
②GetValue8のpredicateと合わせるためstring型引数を受け取ることは宣言
value.Length == 3;で真が返されると、result.Add(val);で値が追加される。

private string[] GetValue8(string[] values, Predicate<string> predicate)//①Predicate型を引数として受け取る
{
    var result = new List<string>();
    foreach (var val in values)
    {
        if (predicate(val))
        {
            result.Add(val);
        };
    }

    return result.ToArray();
}
private void button8_Click(object sender, EventArgs e)
{
    var values = new string[] { "A", "BB", "CCC", "DDDD", "EEEEE" };
    var result = GetValue8(
        values,
        delegate (string value)//②GetValue8のpredicateと合わせる
        {
            return value.Length == 3;
        }
        );
    Console.WriteLine(string.Join(",", result));
}

Func型

戻り値のあるメソッドが定義されている、引数は0~16個まで可。
②引き合数string value, int lenを受け取り、value.Length >= lenの結果を返す。
value.Length >= lenで真だと、result.Add(val);で値が追加される。

private string[] GetValue10(string[] values, int len, 
    Func<string, int, bool> lenCheck) //①引数2つ(string,int)を受け取り、戻り値boolを返す
{
    var result = new List<string>();
    foreach (var val in values)
    {
        if (lenCheck(val, len))
        {
            result.Add(val);
        };
    }

    return result.ToArray();
}

private void button10_Click(object sender, EventArgs e)
{
    var values = new string[] { "A", "BB", "CCC", "DDDD", "EEEEE" };

    var tokumei = GetValue10(values, 2,
                            delegate (string value, int len)//②①のFunc<string, int, bool> lenCheckと合わせる
                            {
                                return value.Length >= len;
                            });
    Console.WriteLine(string.Join(",", tokumei));
}

Action型

戻り値のないメソッドが定義されている、引数は0~16個まで可。
②引数int型を受け取り、戻り値なしのメソッドが実行される。この例では、Console.WriteLine(value);が1秒ごとに5回実行されるため、コンソール上に20,40,60,80,100が表示される。



    private List<string> GetData(Action<int> progressAction) //①引数intを受け取り、戻り値はなし
{
    var result = new List<string>();
    for (int i = 1; i <= 5; i++)
    {
        result.Add(DateTime.Now.ToString("yyyy/dd HH:mm:ss.ff"));
        System.Threading.Thread.Sleep(1000);
        progressAction(i * 20); //②①のAcrion<int>progressActionと合わせる
    }
    return result;
}

private void DoConsole(int value) 
{
    Console.WriteLine(value);
}

private void button12_Click(object sender, EventArgs e)
{
    GetData(DoConsole);
}

参考文献
https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/delegates/
https://anderson02.com/cs/lambda/lambda06/
https://learn.microsoft.com/ja-jp/dotnet/standard/delegates-lambdas
https://learn.microsoft.com/en-us/dotnet/api/system.predicate-1?view=net-8.0
https://learn.microsoft.com/en-us/dotnet/api/system.func-1?view=net-8.0
https://learn.microsoft.com/en-us/dotnet/api/system.action-1?view=net-8.0

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?