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

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

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

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

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

9回答

8212閲覧

オブジェクト指向(C#)における関数の戻り値について

tassi-yuzukko

総合スコア10

C#

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

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

2クリップ

投稿2018/07/26 13:24

編集2018/07/26 13:29

主題の件ですが、関数の返り値として、「結果」ともし失敗した場合は「理由」も返すというような場合に、どのように実装すればよいのか悩んでいます。

説明が難しいので具体例を挙げて質問させていただきます。

具体例

  • 社員データベースのようなものがあって、名前生年月日を引数で与えると、その人の社員番号を返す関数があったとします
  • その関数は、データベースに登録されている名前生年月日があれば、正常に社員番号を返しますが、データベースに登録されていない場合、失敗を返します。
  • その失敗の理由として、例えば「該当の名前なし」とか「該当の生年月日なし」とかが考えられます。
  • 上記の理由で関数が失敗した場合は、呼び出し元にその失敗理由も返します。

(そもそもそんな関数作らないという話もあるでしょうが、あくまで例ですのでご容赦ください。)

質問

このような条件の場合、例えば C# であれば、どのような実装がスマートなのでしょうか。
今まで業務では基本的にC言語ばかりを扱ってきたので、モダンなやり方がわからなくて困っています。
C言語的にやるならば、「成功可否のBOOL値を関数の返り値として、失敗理由をポインタ渡しして・・・」とかがありそうですが。

自分で考えてみた選択肢

out 修飾子を使う

例えば以下のような感じです。なんか手続き型チックで違和感がありますが、一番直?な気もします。

cs

1class EmployeeNumber 2{ 3 int Value {get;} 4 5 public EmployeeNumber(int value) 6 { 7 Value = value; 8 } 9} 10 11// 成功した場合は返り値として社員番号を返す。失敗した場合はnullを返して、FailedReasonに失敗理由を設定して返す。 12EmployeeNumber GetEmployeeNumberBy(string name, DateTime birthDay, out FailedReason failedReason); 13// 本当にやるなら EmployeeNumber をヌルオブジェクトパターン適用すべきですが省略

② タプルで返す

例えば以下のような感じです。これも手続き型脳的には素直な気がします。

cs

1class EmployeeNumber 2{ 3 int Value {get;} 4 5 public EmployeeNumber(int value) 6 { 7 Value = value; 8 } 9} 10 11// 成功した場合は返り値として (社員番号, null) を返す。失敗した場合は (null, 失敗理由) を返す。 12(EmployeeNumber employeeNumber, FailedReason? failedReason) GetEmployeeNumberBy(string name, DateTime birthDay); 13// 本当にやるなら EmployeeNumber をヌルオブジェクトパターン適用すべきですが省略

③ 社員番号クラスの中に失敗理由を埋め込む

例えば以下のような感じです。

cs

1class EmployeeNumber 2{ 3 int Value {get;} 4 FailedReason? FailedReason {get;} 5 6 public EmployeeNumber(int value, FailedReason? failedReason=null) 7 { 8 Value = value; 9 FailedReason = failedReason; 10 } 11} 12 13EmployeeNumber GetEmployeeNumberBy(string name, DateTime birthDay);

④ ダブルディスパッチパターンを使用する

個人的にはこの方法が一番マシなのかなぁと思っています。

cs

1class EmployeeNumber 2{ 3 int Value {get;} 4 5 public EmployeeNumber(int value) 6 { 7 Value = value; 8 } 9} 10 11interface IGetEmployeeNumberFailed 12{ 13 void OnFailedBecauseNotMatchedName(); 14 void OnFailedBecauseNotMatchedBirthDay(); 15} 16 17// 成功した場合は返り値として社員番号を返す。失敗した場合は null を返して失敗理由を与えられたインターフェイスを使用してコールバックする。 18EmployeeNumber GetEmployeeNumberBy(string name, DateTime birthDay, IGetEmployeeNumberFailed onFailed);

⑤ ドメインイベントを発行する

DDD でやるならこれなんでしょうが、個人的にはメリットがあまりピンとこないです。

cs

1class EmployeeNumber 2{ 3 int Value {get;} 4 5 public EmployeeNumber(int value) 6 { 7 Value = value; 8 } 9} 10 11// 成功した場合は返り値として社員番号を返す。失敗した場合はドメインイベントを発行する。 12EmployeeNumber GetEmployeeNumberBy(string name, DateTime birthDay) 13{ 14 // ~~ 省略 ~~ 15 16 // 詳細には書ききれないので、かなり省略します 17 if(名前が見つからなかった) 18 domainEvent.Publisher(new DomainEvent<FailedReason>(FailedReason.NotMatchedName)); 19 if(誕生日が見つからなかった) 20 domainEvent.Publisher(new DomainEvent<FailedReason>(FailedReason.NotMatchedBirthDay)); 21 22 return 社員番号 23}

長くなりましたが

長文となり申し訳ありませんが、「①~⑤のうち●番が良い」とか、「こういう方法が良い」等、ご教授のほど、宜しくお願い致します。
また、これが良いとは言わないまでも、普段こうしているというのがあれば教えていただけると幸いです。

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

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

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

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

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

guest

回答9

0

私なら例外をスローします。

投稿2018/07/26 13:28

Zuishin

総合スコア28660

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

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

tassi-yuzukko

2018/07/26 13:34

早速の回答ありがとうございます。 例があまり良くなかったのですが、これらは一応業務ロジックとさせてください。いわゆるドメイン層でのロジックという感じです。 後出しになって申し訳ありませんが、「この処理が失敗した場合、システムにおいて致命的な状態になるわけではなく、業務ロジックとして失敗がありえる」という位置づけとさせてください。
Zuishin

2018/07/26 13:35

問題ないと思いますが。
len_souko

2018/07/27 03:07

呼び出す側でcatchして例外の型で業務エラーなのかシステムエラーなのかを切り分ければいいかと思います これならば特定のところからは起きるはずのない事態なのでシステムエラーにし、それ以外のところからは後処理を行ってエラー画面に飛ばさないといったことも可能です
Zuishin

2018/07/27 03:40

補足ありがとうございます。 ずっと C 言語の環境だと例外になじみがないかもしれませんね。
fana

2018/07/27 08:58

N個の{名前,生年月日}に対して社員番号を問い合わせる場合,例外だとパフォーマンス悪かったりしないのでしょうか.
Zuishin

2018/07/27 09:20

大量の間違った名前と生年月日から社員番号を一括検索する事態があるとは思えませんが、もしそのようなケースが考えられるのなら、複数の間違いに対して一つの例外を発生させれば良いのではないでしょうか。
Zuishin

2018/07/27 09:26 編集

ドメイン層で例外をスローせずエラーを表す戻り値を返す場合でも、どのみちアプリケーション層で異常出力を判定して例外を発生させる必要があるのではないかと思います。
tassi-yuzukko

2018/07/27 12:42

ありがとうございます。 len_souko 様 javaであれば検査例外(業務エラー)と実行時例外(システムエラー)は明確に区別されるので、この場合は検査例外でよいかと思いますが、C#の場合は区別がつかないので、C#では業務エラーにおいては例外は使用すべきでないという認識でした。 何か有効な切り分け方等ありましたら、ご教授いただけると幸いです。
Zuishin

2018/07/27 12:46

Exception から派生していくらでも例外が作れます。 検査例外を派生させ、そこから更に個々の例外を派生させればいいでしょう。 例外は catch でフィルタリングできます。
tassi-yuzukko

2018/07/27 12:57

Zuishin 様 ありがとうございます。 yuya_tn様のコメントにも書きましたが、C#においては業務エラーで例外を使用すべきでないと勉強していたので、変な回答になってしまい申し訳ありませんでした。 例外も候補に入れて考えてみたいと思います。
Zuishin

2018/07/27 13:12

業務で例外を使うなというのはまともな教えではありません。 すぐに忘れてください。 フレームワーク自体に多く例外が使われています。
len_souko

2018/07/28 03:57

例えば業務システムの自作フレームワーク内での共通処理なんかでそのロジックとしては処理が続行できない状態の場合に、それが業務エラーなのかシステムエラーなのかは判断できないと思います となると、質問者さんの教えられた前提だと共通処理やフレームワーク関係は軒並み例外を出せなくなってしまうので、戻り値には常に正常に処理できた場合の本当の意味での戻り値を格納するクラスとエラー情報を載せるためのクラスをセットにしたクラスを定義しないといけなくなります 常にどちらか一方しか使いません。非常に面倒かつ分かりにくいものになると思われます なので、処理一つ一つで問題があって続行できないものは例外を起こして内容は型(Exceptionから派生した自作クラス)で判別し、詳細情報を例外クラス内部に持たせます で、使う側で~してくださいといったメッセージを表示するだけの業務エラーであるならばそのような処理を行い、システムに異常が起きないと起こりえない場面であるならばcatchせずにそのまま例外を上に丸投げしていけばいいだけなので、何ら問題はありません ひょっとして、業務エラーは例外にするなというのは、「入力項目のうち、必須項目に入力がないまま処理を続行しようとして例外を起こすなんてことはするな、先に入力チェックを行え」という程度の事ではないでしょうか?
len_souko

2018/07/28 04:16

具体例を見直したうえで 1.社員データベースから検索するメソッド=>0件の場合は0件のデータを返す(正常終了) 2.社員番号を返し、レコードがない場合は失敗を返すメソッド=>0件の場合は失敗なのだから該当データなしの例外を発報する 3a.呼び出し側が例えば手入力の検索画面だったら該当データなしの例外をcatchして該当データがありませんとか条件を変更してくださいと言ったメッセージを出力する 3b.一覧で表示した中から選択したデータの取得処理だった場合は他の人がデータを変更したかデータが欠損した恐れがあるのでcatchせずに該当データなしのエラー画面へ飛ばすかcatchして他の人がデータを変更したかもしれない油脂のメッセージを出力させるかする といった感じですかね 2.社員番号を返すメソッドがデータなしでも失敗を返さないのであればstring.Emptyあたりを返すだけにしますが
fana

2018/07/28 06:48

> 複数の間違いに対して一つの例外 N個のうちM個はOKで,N-M個はNGのとき,どのような形になるのでしょうか.その例外に正常に取得できたM個の情報も持たせるのですか?
Zuishin

2018/07/28 08:01

まず間違った名前と生年月日で大量に検索することはまずないということを改めて確認しておきます。 ナンセンスなのですが、それでもそのようなことがある場合、複数の間違いがあったという例外だけで十分かと思います。 それ以上の詳細な情報が欲しい場合はそれにあわせて作ればいいでしょう。 例外にはプロパティを持たせることができますので、正しい戻り値のリストと間違いの詳細のリストを持たせておけばいいのではないでしょうか。
tassi-yuzukko

2018/07/28 13:37 編集

すみません、誤解のないように説明させていただきますが、あくまでシステムエラーやフレームワークのエラー、外因的なエラーは例外を投げるべきという認識です。 要は、「契約による設計」でも取り上げられていますが、「そのメソッドの責任ではない異常」(不変条件を維持できないなんらかの外因的な異常)が発生した場合は例外を投げるべきということは理解しているつもりです。 しかし、メソッドの想定内の異常(つまりここでいう業務エラー)は例外を投げるべきではないとも書かれています。 また、「達人プログラマー」にも、「例外のキャッチが存在しなくても業務フローは成立してなければならない」という旨が記載されています。 名著がともに業務エラーでは例外を投げるべきではないという旨の記載があるのですが、この点についての見解を教えていただければ幸いです。 また、例外としての定義の問題だけでなく、個人的には業務エラーを例外としてしまうと、キャッチし忘れを懸念しなければならないことに不安があります。 プログラムを保守するのが自分だけなら問題ないのですが、大体の場合保守は別の人がやることになることが多いと思います。そのような場合、この「メソッドを使用するときは、この例外を捕捉しないといけない」ということを使い手に意識させるのは難しいと思います。(やるとしてもコメントで知らせるくらいしか思いつきません) システムエラーならば呼び出し元がキャッチするべきではないので問題ないのですが、業務エラーは呼び出し元にキャッチを強制させる必要がでてきます(いわゆる検査例外)。そういう意味で、言語仕様としてシステムエラーと業務エラーの例外の扱い方に切り分けがない以上、むやみに業務エラーを例外として扱うのは危険であるという認識です。 この点については、そのような懸念は杞憂なのでしょうか・・・ それとも、C#においては慣習的に例外とは業務エラーにも使用するので、そんなことを気にすることがナンセンスなのでしょうか。 本題とは話はそれるのですが、せっかくなのでご教授いただければ幸いです。 宜しくお願い致します。
Zuishin

2018/07/28 21:52 編集

その名著を読んでないので文脈がわかりませんが、業務エラーで例外を投げてはならないという考えはナンセンスです。 そこに書いてあるのがこの案件に相当するかどうかは自分でよく読み込んでください。 又聞きの理解が正しいかどうか議論するつもりはありません。 また自分で答えが出ているなら質問する必要はないでしょう。 例外をどうしても使いたくないなら使わず済ませる方法は他の方が書いてくれています。 私は業務エラーで例外を使ってはならない理由はないと思いますし、使っています。 名著の理解について知りたければ別に質問を立てて読んだ人に聞いてみれば良いのではないでしょうか?
tassi-yuzukko

2018/07/29 00:26

なるほど、失礼致しました。 ご回答いただき、どうもありがとうございます。
len_souko

2018/07/29 02:27

呼び出し階層の奥の方で実際のエラーが起きているのにそこで例外を出さない場合、上の方でこのメソッドからの呼び出しの場合は例外にすると設計してしまうとスタックトレースはエラーが起きた場所ではないところから始まってしまうので本当の問題を見つけにくくなるから後々調査する時に困るんですよね 尤も、具体例のパターンだと普通は失敗と設計しないような内容だと思うので正直この場合は自分なら空文字列を返すようにして、呼び出し側で失敗と設計したから例外を発行するような作りになりそうですが
guest

0

本当に「失敗」であればZuishinさんの回答のように私も「例外」にします。しかし、示された具体例であれば、そもそも「条件にあう社員番号が見つからない場合は『失敗』になるのか?」という疑問があります。つまり、検索すること自体は「成功」しているからです。回答者さんは条件にあう社員番号がみつからないことを通常の業務フローであると考えているようですが、そうであれば、それはそもそも「失敗」とは言えません。

考えるべきは検索結果として何を得たいのか、得るべきなのかです。

  • 検索した結果として、0個以上の社員番号または社員オブジェクトのリスト

まず、必要なのは上のことでしょう。該当者がないことを特別扱いすべきではありません。0個以上のリストですので、0個の場合もあれば、1個、はたまた2個以上もありえます。同姓同名同生年月日がいないなんて保証はどこにもないからです。それらをどう解釈するのかはそれを呼び出す側の責任です。

ただこれだけでは足りないと考えているのでしょう。

  • 検索に対する詳細な情報

一致した氏名の数、一致した生年月日の数、検索対象の社員数、データベース検索にかかった時間、そんなものが一緒にわかれば有意義だと考えたのかも知れません。「一致した氏名の数」が0であれば、呼び出し側は「ああ、同じ氏名の人がいないから、該当者リストの空なのか」とわかるでしょう。考えるべきなのは失敗した理由ではなく、検索に対する情報です。そもそも失敗していないのですから。

しかし、具体的な実装をするにあたって、「一致した氏名の数」を出すのはデータベースが通常のSQLであった場合、パフォーマンス的にいい実装にはなりません。なぜなら、二つの条件を一緒にしてデータベースを検索した方が効率的であり、そこには片方だけ一致したのがどれだけの数だったのかというのをデータベースは返さないからです。別途、全く別のSQLを発行する必要になります。本当に、「一致した氏名があるかどうか」が必要であれば別のメソッドとして実装すべきと考えています。それが必要になることは少なく、今回のメソッドに持たせるべきではありません。

では、その他の情報もどうでしょうか?先ほど挙げた例では、たぶん、デバッグ情報として必要なのは「データベース検索にかかった時間」ぐらいでしょう。それ以外は違うメソッドで必要な時だけ呼び出せば良いのであって、このメソッド返す必要がある情報とは思えません。そして、ユーザーにとって有意義なのは「データベース検索にかかった時間」よりも「検索開始を押してから表示までかかった時間」です。つまり、ユーザーにはデバッグ情報など必要が無い、言ってしまえば、メソッドの呼び出し側にはそんな情報は必要は無いということです。デバッグ情報については全く別の手段で(それはアプリ全体で統一された手段で)持たせるべきでしょう。

何を言いたいのかというと、今回の具体例であれば、そもそも「検索した結果として、0個以上の社員番号または社員オブジェクトのリスト」以外は返す必要も無いし、それら以外の情報をそのメソッドから得る必要は無いと考えています。


正直、例があまりよくない、フェアじゃない、と感じます。ぱっと見たとき、私はRailsのfindのようなものを想定しました。ですので、そもそも「該当者がいなかった理由を返す」ということ自体に必要性の無さを感じました。データーベース側に発行するSQL文を想定しても、そのようなものを返すようにはならないと言うこともあったと思います。

結局の所、欲しい結果が何であるのかと言うことです。これがHTTP接続のレスポンスであれば、そのbodyの内容だけではなく、404などのコードも欲しいとなるでしょう。ですので、ほとんどの実装ではそれらを含めたレスポンスオブジェクトを返すようになっています。しかし、今回はただの検索であるため、検索結果が0であるということは、単に検索に一致するものがなかったということが自明であり、理由をそえる必要は無いと感じられます。どうしても、その他の情報を含めたいのであれば、Resultオブジェクトのようなものを作って、その中に結果とその他の情報を含めるのが良いのかも知れません。

投稿2018/07/28 22:59

raccy

総合スコア21735

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

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

tassi-yuzukko

2018/07/29 00:33

ありがとうございます。 おっしゃる通り例が良くないですね。当たり前ですが、DBの応答性などといったシステム面のことも考慮すべきなので、こんな仕様は例で出しても疑問点がいっぱいありそうです。 実際の案件では、こんな例とは異なりますが、DBの応答性よりも「なぜ失敗したのか」というところに重点性を求められているので、別メソッドという線も考えてみたいと思います。
guest

0

ベストアンサー

関数型からEither<L,R>型を輸入する

投稿2018/07/26 14:07

ozwk

総合スコア13521

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

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

tassi-yuzukko

2018/07/27 12:46

Either型という考えというか、そういうものがあることを知らなかったので、非常に興味深く調べさせていただきました。 調べてみた感じですと、 https://mikhail.io/2016/01/validation-with-either-data-type-in-csharp/ あたりにC#での実装がありますね。この記事にも書かれていますが、成功時と失敗時の振る舞いもある程度強制できますし、勉強になりました。ありがとうございます。
guest

0

今どきは、タプルがいいんじゃないですかね。①~⑤中で、他は論外。
例外もいいのですが、例外は、遅いですし、Try文を書かないとだめですし(サボり症)。

タプルは比較的新しい構文なので、場所によっては使うなとかそういうことになるのでしょうが。

とはいえ、タプルを使うようなやり方がイレギュラーというわけでもなくて、
Result用のクラスを作ってやるという方法は昔からあって、(通信周りはそう)
例えば、HTTPClientのGet
その返り値
そのResult用のクラスを作る手間が省けるから、タプルがいいと言っているだけですけど。

投稿2018/07/27 11:34

編集2018/07/27 11:45
kiichi54321

総合スコア1984

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

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

tassi-yuzukko

2018/07/27 12:52

確かにタプルは専用のResultクラスを作るよりはお手軽ですし、私の環境では特にタプル禁止ということもないので、有力な候補となるんですかね。 ありがとうございます。
guest

0

参考情報

  • エラーハンドリング - IPA

https://www.ipa.go.jp/security/awareness/vendor/programmingv2/clanguage.html

...
対処すべきエラーは、その発生が的確に検出されなくてはならない。

古典的なC言語用ライブラリにおいては、関数の戻り値でエラーを表していた。関数の戻り値をチェックしないコーディングがしばしば行われたため、エラーの発生が見逃されがちであるという問題があった。

C++においては「例外(exception)」が導入された。ランタイムライブラリ等はエラーを例外の発生によって通知するようになり、プログラマは例外の発生を無視できなくなった。
...

投稿2018/07/30 21:36

katoy

総合スコア22324

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

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

0

最近の言語はタプルを使えることが多く、タプルが使えるなら
結果とエラーをタプルにして戻すのがわかりやすく、書きやすい、に一票です。

次点で例外。IOやDB関連などのライブラリがエラーを例外として処理していることが多く、
自前のロジックも合わせたほうがスッキリすると判断すれば例外だと思います。

タプル、例外以外はあんまり考えたくないです。

投稿2018/07/27 14:14

daisuke7

総合スコア1563

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

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

0

C からの習慣でしょうか、 out または、 ref です。
戻り値を boolにして判定します。

例外は、使いません。 まあ、結果が失敗するのが例外的なら別ですが、むちゃ遅いです。 (一つの処理で数か所も使うと、体感的にも分かります)

戻り値を boolで、メソッドそのまま、 if文に含める。

タプルは未だ、メリットが実感できてない。 (そういう場面に出会ってない?)

投稿2018/07/27 12:02

pepperleaf

総合スコア6383

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

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

0

個人的にはタプルで全然いいと思うんですが、業務エラーはまぁだいたい例外でやるのが慣例的な感じありますね。

投稿2018/07/26 23:16

yy_tn

総合スコア299

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

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

tassi-yuzukko

2018/07/27 12:50

契約による設計の観点から、C#においては業務エラーを例外で投げるべきでないと教わっていたのですが、実際は業務エラーも例外でやるのが慣例なんですね。 ありがとうございます。
guest

0

成功なら社員番号を返すなら、失敗のときはマイナスの数値を返せばよろしい

で、どっかで、Defineで、-1 は存在しない社員 -2 は定年退職 -3 は懲戒免職 とか定義しておく

投稿2018/07/26 13:54

y_waiwai

総合スコア87747

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

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

tassi-yuzukko

2018/07/27 12:43

その方法もありますね、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問