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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

4356閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2017/02/18 13:55

編集2017/02/20 13:31

###前提・実現したいこと

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

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

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

Taskクラスリファレンス

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

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

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

投稿2017/02/18 14:42

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/02/18 15:13 編集

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

2017/02/18 15:39

回答が今一つだったようです。「一般プログラマーが便利に利用できるためActionが定義されている。また一般プログラマー向けだけでなく提供ライブラリーの中でもActionが利用されている」という点のみ汲み取っていただければよろしいかと思います。 上記でもピンとこない場合はもしかしたら自分が質問意図をつかみきれてないのかも知れません。
退会済みユーザー

退会済みユーザー

2017/02/18 16:32

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

2017/02/21 02:05

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

退会済みユーザー

2017/02/22 14:12

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

0

ベストアンサー

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

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

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

投稿2017/02/20 23:58

tamoto

総合スコア4103

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/02/22 14:14

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問