3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

すばらしきかな、名前付き引数

Last updated at Posted at 2020-06-04

C#入門記事を記載させていただいております。
Windows10+VSCode+.NET CoreでC#開発環境を作ろう!
初めてC#を学習する方へのおすすめサイト

あるある。引数の順番を間違えてしまう

C言語で以下のような関数を書いたとします。

introduce_miss.c
#include <stdio.h>

static void introduce(char *country, char *name)
{
    printf("%sです。 %s出身です。\n", country, name);
}

int main(void)
{
    introduce("東京", "太郎");
    return 0;
}

自己紹介の関数ですね。
実際に使用してみましょう。

東京です。 太郎出身です。

盛大に間違えてますね。
太郎さんは「東京出身の太郎です。」と出力されると思っていたようです。
今回のように、型が同じ関数だと、順番を間違えていてもコンパイラ等では判断できません。
テストするまで、間違えが残ってしまいます。

なんとかして順番ミスをなくしたい

C言語なら構造体を引数に

C言語で無理やり解決しようと思うとこんな感じでしょうか。

introduce_type.c
#include <stdio.h>

typedef struct {
    char *country;
    char *name;
} Profile;

static void introduce(Profile profile)
{
    printf("%sです。 %s出身です。\n", profile.name, profile.country);
}

int main(void)
{
    introduce((Profile){.country="東京", .name="太郎"});
    return 0;
}

順番ミスしなくはなりましたが・・・関数毎に構造体作るわけにもいきませんね。
ちょっとしんどい。

オブジェクト指向言語ならメソッドチェーン

C++であれば、クラス・メソッドを使用できるので以下のようなセッタを作成すると
引数を可視化してコーディングできます。

introduce.cpp
#include <iostream>
#include <string>

using namespace std;

class IntroduceClass
{
public:
    string _country;
    string _name;

    IntroduceClass()
    {
        _country = "日本";
        _name = "名無しの権兵衛";
    }
    IntroduceClass& setCountry(string country)
    {
        _country = country;
        return *this;
    }
    IntroduceClass& setName(string name)
    {
        _name = name;
        return *this;
    }
    static void introduce(const IntroduceClass& ic)
    {
        cout << ic._name + "です。 " + ic._country + "出身です。" << endl;
    }
};

int main()
{
    IntroduceClass::introduce(IntroduceClass().setCountry("東京").setName("太郎"));
    return 0;
}

メソッドチェーンと言われる記載方法ですね。
ちなみに関数呼び出し時に引数名を明示するためのイディオムを名前付きパラメータ・イディオム(Named Parameter Idiom)といいます。

C言語のケースと違ってクラス化を前提としているため、
「関数毎に作る」必要はなくなりました。
ただ、C言語よりも長くなった感じは否めない。

C#なら名前付き引数

C#の場合は、以下のようになります。

Introduce.cs
using System;

namespace NamedArguments
{
    class Introduce
    {
        static void Main(string[] args)
        {
            introduce(name: "太郎", country: "東京");
        }
        static void introduce(string country = "日本", string name = "名無しの権兵衛")
        {
            Console.WriteLine(name + "です。" + country + "出身です。");
        }
    }
}

すばらしくスッキリ!
また、引数が増えてしまった場合だとしても

Introduce.cs
            introduce(
                name: "太郎",
                country: "東京"
            );

関数呼び出し部分を改行して整形することで、JSONのようなスッキリした見栄えになります。
また、サンプルのように初期値を指定しておくことで、
必要なパラメータのみ記載して呼び出すことが可能です。
・・・毎回全パラメータ入力が必要ないのもすばらしい

まとめ

今回は名前付き引数をご紹介させていただきました。
これを使えば、もう引数の順番を気にすることもなければ、
メソッドに引数追加が必要になった際にもある程度安心できますね。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?