🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Q&A

解決済

2回答

1331閲覧

C#、オーバーロードとコレクションについて

cushionA

総合スコア90

C#

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

0グッド

0クリップ

投稿2019/12/14 09:36

編集2019/12/14 10:29

C#のオーバーロードとコレクションについて質問です。

オーバーロードはコンストラクターやメソッドを対象にして行うものですが、いまいちその必要性が理解できなくて困っています。
恐らく根本的な理解の甘さからくる疑問だとは思うのですが、よくわからないのです。

まずシグニチャの異なるメソッドを同じ名前でわざわざ作る理由が分かりません。
オーバーロードするものが必ずしも完全に処理が同じだとも限らないのだから、普通に異なるメソッドとして定義した方が可読性が高まりそうな気がして混乱しています。

コンストラクターについてもそうで、コンストラクターに初期化子でわざわざ引数を渡さなくても引数を増やしたり、ブロックの式を増やして対応できないものでしょうか。

例えば以下のコードですが

C#

1class Dog 2{ 3 public Dog() : this("犬はかわいい") 4 { 5 System.Console.WriteLine("とてもかわいい"); 6 } 7 public Dog(string copy) 8 { 9 System.Console.WriteLine(copy); 10 } 11} 12

これは

C#

1 2class Dog 3{ 4 public Dog(string copy) 5 { 6 copy = "犬はかわいい" 7 8   System.Console.WriteLine(copy); 9 System.Console.WriteLine("とてもかわいい"); 10} 11

こちらのコードと同義ではないのでしょうか?
正直オーバーロードを使う必要性があまり分からないのですが、どうかご教授願いたいです。

こうしてプログラミングの基礎として教本に乗ってる以上は確かな実用性がある手法であるのは間違いないでしょうし、僕もそれを使いこなせるようになりたいのです。

また、コレクションについてですが

・リストは動的に容量が変わる配列、つまり順番でデータを管理する時に。
・セットは集合、集団同士の要素の重なりや重複を確かめたい時に。
・ディクショナリはデータとデータを紐づけて管理したい時に用いる。

というような認識で構わないでしょうか、というのが質問でございます。

初歩的な上に長い質問になってしまいまして申し訳ありませんが、どうか良い知恵をお借りしたいです。
よろしくお願いいたします。

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

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

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

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

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

YAmaGNZ

2019/12/14 09:54 編集

同義どころか、コンパイル通りません。
cushionA

2019/12/14 10:07 編集

すみません 実際にビジュアルスタジオに打ち込んでみたのですが、unity用のコードしか扱ったことがないのでコンパイルの仕方がよく分かりません。 デバッグも試してみたのですが動いてくれませんでした。 赤線の指摘はないようなのですが、お手間をおかけして恐縮なのですが問題点を教えてくださると大変助かります。 申し訳ありません。
YAmaGNZ

2019/12/14 10:13

public Dog(string copy) { string copy = "犬はかわいい"; これは同一スコープに同一名称の変数を定義しようとしているために CS0136 ローカルまたはパラメーター 'copy' は、その名前が外側のローカルのスコープでローカルやパラメーターの定義に使用されているため、このスコープでは宣言できません。 とエラーとなります。
cushionA

2019/12/14 10:27 編集

なるほど、ご丁寧な解説に感謝いたします。 この場合はthisをつければエラーは解消されるでしょうか? ポンコツで申し訳ないです。
YAmaGNZ

2019/12/14 10:24

とりあえずの例でしたら public Dog(string copy) { copy = "犬はかわいい"; でいいのではないかと思います。
cushionA

2019/12/14 10:28

再三のご回答感謝いたします。 代入の仕方を失念しておりました。 質問以前の問題で長々とお手を煩わせてしまい申し訳ありませんでした。
Zuishin

2019/12/14 11:17

この条件に限って言えばオプション引数を使えばオーバーロードを使わなくても同じものを作ることはできますね。 ただし、数値(位置)と文字列(名前)のどちらか片方を引数に処理を行いたい場合などにはオーバーロードが必要になります。
Zuishin

2019/12/14 12:24

サブアカウントかな?
cushionA

2019/12/14 12:48

回答ありがとうございます。 そしてすみません。 オプション変数はまだやっていないのでググった程度の知識しかなく、完全には理解できませんでした。 しかしやはり、処理が込みいればオーバーロードは必要なのですね。 ありがとうございます。 いえ、モロにメインアカウントです。 誤解があったなら申し訳ありません。
退会済みユーザー

退会済みユーザー

2019/12/14 13:13

>オーバーロードするものが必ずしも完全に処理が同じだとも限らないのだから これに関して言えばそういう「命名と処理が一致しない記述をしない」あるいは「処理に対して正しい命名をする」ことが大切なのであって、一致しない可能性があるから別の名前にする方が良い、という考えは本末転倒です。 同じ理屈で言えば、仮にオーバーロードせずに別のメソッドにしたとして、そのメソッドの名称と処理内容が合致しているとは限らないのではないでしょうか? 命名はそれだけで議論が起きるほど大切なものです。 コンストラクタのオーバーロードが必要なケースについて、例えばDogのインスタンスを生成するのに、Dogの両親2匹(Dog father, Dog mother)を入力にしたい場合と、犬種(string breed)を指定して生成したい場合があったらオーバーロードが必要になると思いませんか? どちらも結果的に生成されるものは同じDogです。その後の振る舞いが同じDogであるならば別名をつけて他のクラスで、という訳にも行かないですよね。
cushionA

2019/12/14 13:20

ご指導ありがとうございます。 わかりやすい例えが添えてあったおかげで、大変参考になりました。 僕は命名というものをどこか個人名のように考えていたからか、それを同じにするという行為を馴染まないように感じていました。 しかし役割に与えるある種ラベルのようなものだと考えると、むしろいちいち違うものを貼り付ける方が違和感がありますし、個人名としてよりラベルとして扱ったほうが利便性は高そうにも感じます。 「命名と処理が一致するように名付ける」そして、その結果あるのがオーバーロードなのですね。 勉強になりました、ありがとうございます。
guest

回答2

0

ちなみに例に挙げられているコードですが、同義ではありません。

C#

1 class Dog1 2 { 3 public Dog1() : this("犬はかわいい") 4 { 5 System.Console.WriteLine("とてもかわいい"); 6 } 7 public Dog1(string copy) 8 { 9 System.Console.WriteLine(copy); 10 } 11 } 12 13 class Dog2 14 { 15 public Dog2(string copy) 16 { 17 copy = "犬はかわいい"; 18 19 System.Console.WriteLine(copy); 20 System.Console.WriteLine("とてもかわいい"); 21 } 22 } 23

こうあった場合に

C#

1Dog1 d1_1 = new Dog1(); 2//犬はかわいい 3//とてもかわいい 4Dog1 d1_2 = new Dog1("犬は怖い"); 5//犬は怖い 6 7// Dog2 d2_1 = new Dog2(); 8//コンパイルエラー 9Dog2 d2_2 = new Dog2("犬は怖い"); 10//犬はかわいい 11//とてもかわいい 12

このような結果になります。

投稿2019/12/14 10:47

YAmaGNZ

総合スコア10469

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

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

cushionA

2019/12/14 11:48 編集

引き続きのご助言に感謝いたします。 確かに犬は怖いを入れる場所がなくなってしまいますね……。 コーディングってとても難しいですね。 未熟者なのだから無難にオーバーロードに頼っておくべきでした……。
guest

0

ベストアンサー

ほとんど同じ処理で対象が違うだけ、とか、
同じ処理でオプションが付いてるだけ、とか、
同じ名前をつけれると便利なことが多いです。

まあ、それぞれ別の名前つけてもいいんですが、何よりめんどくさいでしょう。
本来、プログラマというのはズボラなのがいいプログラマです。

投稿2019/12/14 10:13

y_waiwai

総合スコア88038

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

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

cushionA

2019/12/14 10:20

回答していただき誠にありがとうございました。 なるほど……。 確かにaddなどよく使いたいワードがありますね。 そういうことで同じ名前のメソッドを用いていたのですね。 コンストラクターについてはもとより名前は固定されていますが、処理を一つにまとめるのではなくオーバーロードするのはズボラ的に言うとあとから付け加えるのが簡単だからと、そういうことになるのでしょうか?
y_waiwai

2019/12/14 10:27

プログラム言語における新機能ってのは、なによりズボラするためのもの、ですぜ #異論はみとめようw
cushionA

2019/12/14 10:33 編集

ありがとうございますw 煮詰まっていたのですが、なんだか朗らかな気持ちになれました。 ずぼらだったんですね。 でも、言われてみればすごく便利です。 ご鞭撻に感謝いたします。 コレクションについては自分で調べる余地もまだまだありそうなので、これにて解決済みとさせて頂きます。 YAmaGNZ様とy_waiwai様、付き合ってくださったご両名に感謝いたします。
len_souko

2019/12/14 11:26

煮詰まってるんなら解決してるのとほぼ同じやん =>疑問に思った場合は辞書で調べてください オーバーロードがなかったら 同じ目的のメソッドなのに引数の違いで全部違うメソッド名で定義する必要があります 定義するのも面倒ですが、使う際にも同じ名前なら目的も同じだと分かるけども違う名前なら目的が違うかのように見えるので例えば開発者が引き継いで別の人になった場合に、同じことをする引数も同じなのに、その時の開発者の考え方の相違によってメソッド名が別のものを定義することになるかもしれません それを使用しようとしたらいったい何がどうちゃうねん!!ってなりますよね
cushionA

2019/12/14 11:34

すみません……言葉の意味を間違えてたようです。 行き詰まってたと混同してました……。 回答ありがとうございます。 なるほど、メソッドをそれ単体ではなく用途別に見るのですね。 確かに使いみちが似ているのなら名前が同じ方が見返した時、引き継いだ時便利になりそうです。 使いやすさといいますか、そういったものを意識するなら大きな違いですね。 貴重なアドバイスありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問