質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • C#

    7119questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    4004questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

デリゲート型のAction型について。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,117

tkmnusr

score 162

前提・実現したいこと

デリゲート型のAction型は、何の為にありますか?
デリゲート型で汎用的に使われるものを、定義する手間を省く為に、定義済みのAction型があるということなのでしょうか?
どういった使い方ができますか?

「一般プログラマーが便利に利用できるためActionが定義されている」というのが、
「デリゲートを定義する手間を省く為に、Actionが定義されている」という意味でしょうか?

補足情報(言語/FW/ツール等のバージョンなど)

Unity 5.5.0f3

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+4

デリゲートを定義する手間を省く為に存在しているのでしょうか?

そういう面もあると思います。ただそれだけではないと思います。

Taskクラスリファレンス

上記は.NETライブラリーにあるTaskクラスのリファレンスですが、メソッドの一覧を見るとActionを引数とするものがあることに気づきます。つまり提供ライブラリーのインターフェースを規定するためにActionを定義・提供することが必要であるという面です。

概ね有用性の高いクラスというは単に単独でユーザーへ提供するだけではなくライブラリーを構成する他の機能と有機的に組み合わさって用いられているということは珍しくなくActionもまたその一つと言えるでしょう。

むしろ逆の見方もできると思います。.NETなどのライブラリーの設計において、各々の機能を構成する際にその機能専用のクラス(特化クラスとでもいいましょうか)を個別に作るのではなく、特別な理由がないかぎり一般化可能なクラスとして個々の部品を設計し、「似たような機能のクラスをやたら増やす」ことを避けて「機能を単純明快にした部品の集合として」設計することがこころがけられているという見方です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/19 00:13 編集

    ご回答ありがとうございます。
    初心者の為、ご回答者様のご回答が理解できるように勉強して参ります。

    キャンセル

  • 2017/02/19 00:39

    回答が今一つだったようです。「一般プログラマーが便利に利用できるためActionが定義されている。また一般プログラマー向けだけでなく提供ライブラリーの中でもActionが利用されている」という点のみ汲み取っていただければよろしいかと思います。

    上記でもピンとこない場合はもしかしたら自分が質問意図をつかみきれてないのかも知れません。

    キャンセル

  • 2017/02/19 01:32

    ご回答ありがとうございます。
    前者の「一般プログラマーが便利に利用できるためActionが定義されている」というのが、「デリゲートを定義する手間を省く為に、Actionが定義されている」という意味でしょうか?

    キャンセル

  • 2017/02/21 11:05

    そうですね。tamotoさんの回答がわかりやすいと思います。
    delegateというのは要するに「コールすることができるもの」を表現するc#の機能の一つですがこれは他の言語でもよく出てくるいわゆる「関数オブジェクト」を表現するものです。関数オブジェクトを利用するには「引数の型と個数および戻り値の型」を規定する必要がありますのでdelegateを利用する際にそれを規定(定義)する必要があるわけですが、tamotoさん回答にあるようにc#がジェネリクスをサポートしたため、一部の制限を除き大抵の関数オブジェクトをAction, Funcの2つのジェネリクス型として定義できるようになったのでプログラマーが一々それらを定義しなくてよいようにMicrosoftがこの二つの型を定義して提供したと捉えるのが分かりやすいと思います。

    キャンセル

  • 2017/02/22 23:12

    ご回答ありがとうございます。
    理解できました、ありがとうございます。
    今回、回答者様もtamoto様をわかりやすいとおっしゃっているので、今回はtamoto様をベストアンサーに選びたいと思います。ありがとうございました。

    キャンセル

checkベストアンサー

+2

こんにちは。
名前付きデリゲートが使われていた頃には、C#に「ジェネリクス」が存在していませんでした。引数に関数を取りたい場合、型を決め打ちするしかなかったため、自分の使うデリゲートを名前付きで定義するのが自然だったのです。
そのため、名前付きデリゲートはたとえメソッドとしてのシグネチャが同じであっても「型が違う」ため、相互に代入することはできないようになっています。
ジェネリクスが実装され、そのしばらく後にジェネリックデリゲートであるActionとFuncが登場しました。知っての通り、メソッドのパラメータや戻り値の型が全て型パラメータとなっているため、殆どの関数をどれかのジェネリックデリゲートにマッチさせることができます。自分で名前付きデリゲートを定義する必要がなくなったわけです。
そして、標準ライブラリから有名なサードパーティライブラリまで、ジェネリックデリゲートを利用するようになり、名前付きデリゲートが表に出てこなくなったため、「デリゲート間の変換ができない」問題が消極的に解決しました。
C#4.0以降はジェネリックデリゲートに共変/反変のサポートが入り、さらに使い勝手が良くなりました。

というわけで、強気な結論を述べると、「名前付きデリゲートはジェネリクスすら存在しなかった過去のC#の遺物であり、今後使用するのは控えるべき」です。Action、Funcが対応する場面では必ずそちらを利用するようにしましょう。

ジェネリックデリゲートにも弱点はあり、引数の個数が16以下までしか実装されていない、out/refなどのキーワードに対応したものが実装されていない、というものがあります。これらをデリゲートで扱いたい場合は、名前付きデリゲートを定義するしか方法がありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/22 23:14

    ご回答ありがとうございます。
    Action、Funcを優先的に使い、それらが対応できない時のみ、名前付きデリゲートを使うのですね。
    理解できました、ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    この文の意味を教えてください。

        protected List< List<Material> >m_actual_materials;     protected int m_instance_coun

  • 受付中

    Task.Runの書き方でわからないところが

    前提・実現したいこと C#をVisual Studio2013を使って学習しています。 発生している問題・エラーメッセージ Task.Runを使って別スレッドでなにかする

  • 解決済

    Unityにてダイアログを実装したい。

    Unityにていわゆる「ダイアログ」を作ろうとしています。 ダイアログには「OK」「Cancel」などのボタンが付いており、呼び出すと画面にダイアログが表示され、押したボタンによ

  • 解決済

    ラムダ式内(戻り値部分で使用)でテキストボックスに値をいれたい

    C#のクラスメソッドの返り値にラムダ式を設定し、その内で、Formのテキストボックスに文字を表示させようとしましたがうまくいきません。クラスの生成時に、Formのインスタンス(th

  • 受付中

    Cocoaアプリ上でのScrollViewリサイズについて

    OSXアプリをSwiftで作成しております。 アプリ上でマウスにより手動でScrollViewの移動またサイズ変更を行いたいと思っていますが、 どのような方法で行えば良いか検討が付

  • 解決済

    属性によるメソッド呼び出し

     前提・実現したいこと メソッドに自作属性を付加し、そのメソッドが実行されたあと、自作属性内のメソッドが実行されるようにしたい。  発生している問題・エラーメッセージ  該当の

  • 解決済

    引数ありの時のInvokeの書き方がわかりません。

     前提・実現したいこと Visual Studio C#のInvokeを教えてください。 引数なしの時はかけたのですが、引数ありの時の書き方がわかりません。 よろしくお願いいたしま

  • 解決済

    case文の場合分けが多過ぎる問題

    命令文が1行ごとに連なったテキストファイル(下記のPlain text)を読み込んで、 その行の命令を実行するプログラム(下記C#)を作成しています。 下記のようなプログラムだ

同じタグがついた質問を見る

  • C#

    7119questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    4004questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。